openMSX
MSXCommandController.cc
Go to the documentation of this file.
3 #include "Reactor.hh"
4 #include "MSXEventDistributor.hh"
5 #include "MSXMotherBoard.hh"
6 #include "SettingsManager.hh"
7 #include "InfoCommand.hh"
8 #include "Interpreter.hh"
9 #include "Setting.hh"
10 #include "Event.hh"
11 #include "MSXException.hh"
12 #include "stl.hh"
13 #include <iostream>
14 #include <memory>
15 
16 using std::string;
17 using std::string_view;
18 
19 namespace openmsx {
20 
22  GlobalCommandController& globalCommandController_,
23  Reactor& reactor_,
24  MSXMotherBoard& motherboard_,
25  MSXEventDistributor& msxEventDistributor_,
26  const std::string& machineID_)
27  : globalCommandController(globalCommandController_)
28  , reactor(reactor_)
29  , motherboard(motherboard_)
30  , msxEventDistributor(msxEventDistributor_)
31  , machineID(strCat("::", machineID_, "::"))
32 {
33  globalCommandController.getInterpreter().createNamespace(machineID);
34 
35  machineInfoCommand = std::make_unique<InfoCommand>(*this, "machine_info");
36  machineInfoCommand->setAllowedInEmptyMachine(true);
37 
38  msxEventDistributor.registerEventListener(*this);
39 }
40 
42 {
43  msxEventDistributor.unregisterEventListener(*this);
44 
45  machineInfoCommand.reset();
46 
47  #ifndef NDEBUG
48  for (auto* c : commandMap) {
49  std::cout << "Command not unregistered: " << c->getName() << '\n';
50  }
51  for (auto* s : settings) {
52  std::cout << "Setting not unregistered: " << s->getFullName() << '\n';
53  }
54  assert(commandMap.empty());
55  assert(settings.empty());
56  #endif
57 
58  globalCommandController.getInterpreter().deleteNamespace(machineID);
59 }
60 
61 string MSXCommandController::getFullName(string_view name)
62 {
63  return strCat(machineID, name);
64 }
65 
66 void MSXCommandController::registerCommand(Command& command, const string& str)
67 {
68  assert(!hasCommand(str));
69  assert(command.getName() == str);
70  commandMap.insert_noDuplicateCheck(&command);
71 
72  string fullname = getFullName(str);
73  globalCommandController.registerCommand(command, fullname);
74  globalCommandController.registerProxyCommand(str);
75 
76  command.setAllowedInEmptyMachine(false);
77 }
78 
79 void MSXCommandController::unregisterCommand(Command& command, string_view str)
80 {
81  assert(hasCommand(str));
82  assert(command.getName() == str);
83  commandMap.erase(str);
84 
85  globalCommandController.unregisterProxyCommand(str);
86  string fullname = getFullName(str);
87  globalCommandController.unregisterCommand(command, fullname);
88 }
89 
91  string_view str)
92 {
93  string fullname = getFullName(str);
94  globalCommandController.registerCompleter(completer, fullname);
95 }
96 
98  string_view str)
99 {
100  string fullname = getFullName(str);
101  globalCommandController.unregisterCompleter(completer, fullname);
102 }
103 
105 {
106  setting.setPrefix(machineID);
107 
108  settings.push_back(&setting);
109 
110  globalCommandController.registerProxySetting(setting);
111  globalCommandController.getSettingsManager().registerSetting(setting);
112  globalCommandController.getInterpreter().registerSetting(setting);
113 }
114 
116 {
117  move_pop_back(settings, rfind_unguarded(settings, &setting));
118 
119  globalCommandController.unregisterProxySetting(setting);
120  globalCommandController.getInterpreter().unregisterSetting(setting);
121  globalCommandController.getSettingsManager().unregisterSetting(setting);
122 }
123 
125 {
126  auto it = commandMap.find(name);
127  return (it != end(commandMap)) ? *it : nullptr;
128 }
129 
130 bool MSXCommandController::hasCommand(string_view command) const
131 {
132  return findCommand(command) != nullptr;
133 }
134 
136  CliConnection* connection)
137 {
138  return globalCommandController.executeCommand(command, connection);
139 }
140 
142 {
143  return motherboard.getMSXCliComm();
144 }
145 
147 {
148  return globalCommandController.getInterpreter();
149 }
150 
151 void MSXCommandController::signalMSXEvent(
152  const std::shared_ptr<const Event>& event, EmuTime::param /*time*/)
153 {
154  if (event->getType() != OPENMSX_MACHINE_ACTIVATED) return;
155 
156  // simple way to synchronize proxy settings
157  for (auto* s : settings) {
158  try {
160  s->getFullNameObj(), s->getValue());
161  } catch (MSXException&) {
162  // ignore
163  }
164  }
165 }
166 
168 {
169  return reactor.getMotherBoard() == &motherboard;
170 }
171 
173 {
174  const auto& fromPrefix = from.getPrefix();
175  auto& manager = globalCommandController.getSettingsManager();
176  for (auto* s : settings) {
177  if (auto* fromSetting = manager.findSetting(fromPrefix, s->getBaseName())) {
178  if (!fromSetting->needTransfer()) continue;
179  try {
181  s->getFullNameObj(), fromSetting->getValue());
182  } catch (MSXException&) {
183  // ignore
184  }
185  }
186  }
187 }
188 
189 } // namespace openmsx
void transferSettings(const MSXCommandController &from)
Transfer setting values from one machine to another, used for during &#39;reverse&#39;.
Contains the main loop of openMSX.
Definition: Reactor.hh:66
TclObject executeCommand(const std::string &command, CliConnection *connection=nullptr) override
Execute the given command.
MSXCommandController(const MSXCommandController &)=delete
void registerProxyCommand(const std::string &name)
bool isActive() const
Returns true iff the machine this controller belongs to is currently active.
void setPrefix(std::string_view prefix)
Set a machine specific prefix.
Definition: Setting.hh:40
void unregisterSetting(BaseSetting &setting)
void deleteNamespace(const std::string &name)
Delete the global namespace with given name.
Definition: Interpreter.cc:436
void registerCompleter(CommandCompleter &completer, std::string_view str) override
(Un)register a command completer, used to complete build-in Tcl cmds
void unregisterSetting(Setting &setting) override
Send when a machine is (de)activated.
Definition: Event.hh:62
void registerEventListener(MSXEventListener &listener)
Registers a given object to receive certain events.
void move_pop_back(VECTOR &v, typename VECTOR::iterator it)
Erase the pointed to element from the given vector.
Definition: stl.hh:177
Command * findCommand(std::string_view name) const
const std::string & getName() const
Definition: Completer.hh:20
MSXMotherBoard * getMotherBoard() const
Definition: Reactor.cc:368
void unregisterProxyCommand(std::string_view name)
void registerCommand(Command &command, const std::string &str) override
(Un)register a command
Interpreter & getInterpreter() override
const std::string & getPrefix() const
void registerSetting(BaseSetting &setting)
void setAllowedInEmptyMachine(bool value)
Definition: Command.hh:64
void unregisterEventListener(MSXEventListener &listener)
Unregisters a previously registered event listener.
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
void unregisterCommand(Command &command, std::string_view str) override
void unregisterCompleter(CommandCompleter &completer, std::string_view str) override
bool hasCommand(std::string_view command) const override
Does a command with this name already exist?
void registerCompleter(CommandCompleter &completer, std::string_view str) override
(Un)register a command completer, used to complete build-in Tcl cmds
void unregisterCommand(Command &command, std::string_view str) override
void createNamespace(const std::string &name)
Create the global namespace with given name.
Definition: Interpreter.cc:431
void setVariable(const TclObject &name, const TclObject &value)
Definition: Interpreter.cc:239
void registerCommand(Command &command, const std::string &str) override
(Un)register a command
void registerSetting(Setting &setting) override
TODO.
std::string strCat(Ts &&...ts)
Definition: strCat.hh:573
void unregisterCompleter(CommandCompleter &completer, std::string_view str) override
auto rfind_unguarded(RANGE &range, const VAL &val)
Similar to the find(_if)_unguarded functions above, but searches from the back to front...
Definition: stl.hh:152
void registerSetting(BaseSetting &variable)
Definition: Interpreter.cc:261
TclObject executeCommand(const std::string &command, CliConnection *connection=nullptr) override
Execute the given command.
void unregisterSetting(BaseSetting &variable)
Definition: Interpreter.cc:313