Skip to content

Commit a5da87a

Browse files
author
Gin
committed
create template file for programs
1 parent 1473395 commit a5da87a

File tree

3 files changed

+232
-33
lines changed

3 files changed

+232
-33
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* Program Name
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "CommonFramework/Notifications/ProgramNotifications.h"
8+
#include "CommonFramework/ProgramStats/StatsTracking.h"
9+
#include "CommonTools/StartupChecks/VideoResolutionCheck.h"
10+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
11+
12+
namespace PokemonAutomation{
13+
namespace NintendoSwitch{
14+
namespace GameName{
15+
16+
17+
ProgramName_Descriptor::ProgramName_Descriptor()
18+
: SingleSwitchProgramDescriptor(
19+
"GameName:ProgramName",
20+
"Game Name", "Program Name",
21+
"ComputerControl/blob/master/Wiki/Programs/GameName/ProgramName.md",
22+
"<Description of this program>.",
23+
FeedbackType::REQUIRED,
24+
AllowCommandsWhenRunning::DISABLE_COMMANDS,
25+
{ControllerFeature::NintendoSwitch_ProController},
26+
FasterIfTickPrecise::NOT_FASTER
27+
)
28+
{}
29+
struct ProgramName_Descriptor::Stats : public StatsTracker{
30+
Stats()
31+
: m_attempts(m_stats["Attempts"])
32+
, m_errors(m_stats["Errors"])
33+
{
34+
m_display_order.emplace_back("Attempts");
35+
m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO);
36+
}
37+
std::atomic<uint64_t>& m_attempts;
38+
std::atomic<uint64_t>& m_errors;
39+
};
40+
std::unique_ptr<StatsTracker> ProgramName_Descriptor::make_stats() const{
41+
return std::unique_ptr<StatsTracker>(new Stats());
42+
}
43+
44+
45+
46+
ProgramName::ProgramName()
47+
: GO_HOME_WHEN_DONE(false)
48+
, NOTIFICATION_STATUS_UPDATE("Status Update", true, false, std::chrono::seconds(3600))
49+
, NOTIFICATIONS({
50+
&NOTIFICATION_STATUS_UPDATE,
51+
&NOTIFICATION_PROGRAM_FINISH,
52+
&NOTIFICATION_ERROR_RECOVERABLE,
53+
&NOTIFICATION_ERROR_FATAL,
54+
})
55+
{
56+
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
57+
PA_ADD_OPTION(NOTIFICATIONS);
58+
}
59+
60+
61+
void ProgramName::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
62+
assert_16_9_720p_min(env.logger(), env.console);
63+
64+
ProgramName_Descriptor::Stats& stats = env.current_stats<ProgramName_Descriptor::Stats>();
65+
66+
// Connect the controller.
67+
pbf_press_button(context, BUTTON_L, 10, 100);
68+
69+
try{
70+
71+
} catch(OperationFailedException&){
72+
stats.m_errors++;
73+
env.update_stats();
74+
throw;
75+
}
76+
77+
env.update_stats();
78+
GO_HOME_WHEN_DONE.run_end_of_program(context);
79+
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
80+
}
81+
82+
83+
84+
85+
86+
87+
}
88+
}
89+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* Program Name
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_GameName_ProgramName_H
8+
#define PokemonAutomation_GameName_ProgramName_H
9+
10+
#include "CommonFramework/Notifications/EventNotificationsTable.h"
11+
#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h"
12+
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
13+
14+
namespace PokemonAutomation{
15+
16+
class OperationFailedException;
17+
18+
namespace NintendoSwitch{
19+
namespace GameName{
20+
21+
22+
23+
class ProgramName_Descriptor : public SingleSwitchProgramDescriptor{
24+
public:
25+
ProgramName_Descriptor();
26+
27+
struct Stats;
28+
virtual std::unique_ptr<StatsTracker> make_stats() const override;
29+
};
30+
31+
32+
33+
class ProgramName : public SingleSwitchProgramInstance{
34+
public:
35+
ProgramName();
36+
virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override;
37+
38+
private:
39+
40+
private:
41+
42+
GoHomeWhenDoneOption GO_HOME_WHEN_DONE;
43+
44+
45+
EventNotificationOption NOTIFICATION_STATUS_UPDATE;
46+
EventNotificationsOption NOTIFICATIONS;
47+
};
48+
49+
50+
51+
52+
}
53+
}
54+
}
55+
#endif

SerialPrograms/Scripts/build_code_from_template.py

Lines changed: 88 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,71 @@
99
1010
- python3 build_code_from_template.py VisualDetector PokemonSV Map PokeCenter Icon
1111
Generates PokemonSV_MapPokeCenterIconDetector.h and PokemonSV_MapPokeCenterIconDetector.cpp.
12+
- python3 build_code_from_template.py Program PokemonSV Auto Story
13+
Generates PokemonSV_AutoStory.h and PokemonSV_AutoStory.cpp.
1214
"""
1315

1416
import sys
1517
import os
1618

17-
from typing import Dict
19+
from typing import Dict, List
20+
21+
22+
def apply_line_replacement(line: str, mapping: Dict[str, str]) -> str:
23+
for source, target in mapping.items():
24+
line = line.replace(source, target)
25+
return line
26+
27+
28+
def build_file_from_template(
29+
mapping: Dict[str, str],
30+
template_folder: str,
31+
template_filename: str,
32+
) -> None:
33+
"""
34+
generate a file from a template file by mapping: template str -> target str
35+
The file is saved at the current working dir.
36+
"""
37+
38+
file_ext: str = template_filename.split('.')[-1]
39+
template_filepath: str = os.path.join(template_folder, template_filename)
40+
41+
target_filename: str = apply_line_replacement(template_filename, mapping)
42+
43+
with open(template_filepath, "r") as f:
44+
lines = f.readlines()
45+
lines = [apply_line_replacement(line, mapping) for line in lines]
46+
47+
with open(target_filename, "w", newline='\r\n') as f:
48+
f.writelines(lines)
49+
50+
print(f"Saved template {file_ext} file to {target_filename}")
51+
52+
53+
def build_files_from_templates(
54+
mapping: Dict[str, str],
55+
template_folder: str,
56+
template_filenames: List[str],
57+
) -> None:
58+
"""
59+
generate files from template files by a mapping: template str -> target str
60+
The files are saved at the current working dir.
61+
"""
62+
63+
for filename in template_filenames:
64+
build_file_from_template(
65+
mapping=mapping,
66+
template_folder=template_folder,
67+
template_filename=filename,
68+
)
69+
70+
71+
def create_cpp_class_name(name: str) -> str:
72+
"""
73+
Given a name (e.g. "Three-Segment Dudunsparce Finder"), convert it into a C++ class name (like "ThreeSegmentDudunsparceFinder")
74+
"""
75+
return name.replace(" ", "").replace("-", "").replace("_", "")
76+
1877

1978
if len(sys.argv) == 1:
2079
print(
@@ -36,11 +95,7 @@
3695
template_folder = os.path.join(code_root_path, "SerialPrograms", "Scripts", "CodeTemplates")
3796
print(f"Template folder: {template_folder}")
3897

39-
40-
def apply_replacement(line: str, mapping: Dict[str, str]) -> str:
41-
for source, target in mapping.items():
42-
line = line.replace(source, target)
43-
return line
98+
template_folder = os.path.join(template_folder, sys.argv[1])
4499

45100
if sys.argv[1] == "VisualDetector":
46101
assert len(sys.argv) >= 4
@@ -51,38 +106,38 @@ def apply_replacement(line: str, mapping: Dict[str, str]) -> str:
51106
mapping = {
52107
"GameName": game_name,
53108
"Object Name": object_name,
54-
"ObjectName": object_name.replace(" ", ""),
109+
"ObjectName": create_cpp_class_name(object_name)
55110
}
56111

57-
template_h_filename = "GameName_ObjectNameDetector.h"
58-
template_cpp_filename = "GameName_ObjectNameDetector.cpp"
59-
60-
template_folder = os.path.join(template_folder, sys.argv[1])
61-
62-
template_h_filepath = os.path.join(template_folder, template_h_filename)
63-
template_cpp_filepath = os.path.join(template_folder, template_cpp_filename)
64-
65-
target_h_filename = apply_replacement(template_h_filename, mapping)
66-
target_cpp_filename = apply_replacement(template_cpp_filename, mapping)
67-
68-
69-
with open(template_h_filepath, "r") as f:
70-
lines = f.readlines()
71-
lines = [apply_replacement(line, mapping) for line in lines]
72-
73-
with open(target_h_filename, "w", newline='\r\n') as f:
74-
f.writelines(lines)
112+
build_files_from_templates(
113+
mapping=mapping,
114+
template_folder=template_folder,
115+
template_filenames=[
116+
"GameName_ObjectNameDetector.h",
117+
"GameName_ObjectNameDetector.cpp",
118+
]
119+
)
120+
elif sys.argv[1] == "Program":
121+
assert len(sys.argv) >= 4
122+
game_name = sys.argv[2] # e.g. "PokemonSV"
123+
program_name = " ".join(sys.argv[3:]) # e.g. "Auto Story"
124+
print(f"Building a Program with name {program_name} in game {game_name}.")
75125

76-
print(f"Saved template h file to {target_h_filename}")
126+
mapping = {
127+
"GameName": game_name,
128+
"Program Name": program_name,
129+
"ProgramName": create_cpp_class_name(program_name)
130+
}
77131

78-
with open(template_cpp_filepath, "r") as f:
79-
lines = f.readlines()
80-
lines = [apply_replacement(line, mapping) for line in lines]
81-
82-
with open(target_cpp_filename, "w", newline='\r\n') as f:
83-
f.writelines(lines)
132+
build_files_from_templates(
133+
mapping=mapping,
134+
template_folder=template_folder,
135+
template_filenames=[
136+
"GameName_ProgramName.h",
137+
"GameName_ProgramName.cpp",
138+
]
139+
)
84140

85-
print(f"Saved template cpp file to {target_cpp_filename}")
86141

87142

88143

0 commit comments

Comments
 (0)