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 
18 namespace openmsx {
19 
21  GlobalCommandController& globalCommandController_,
22  Reactor& reactor_,
23  MSXMotherBoard& motherboard_,
24  MSXEventDistributor& msxEventDistributor_,
25  const std::string& machineID_)
26  : globalCommandController(globalCommandController_)
27  , reactor(reactor_)
28  , motherboard(motherboard_)
29  , msxEventDistributor(msxEventDistributor_)
30  , machineID(strCat("::", machineID_, "::"))
31 {
32  globalCommandController.getInterpreter().createNamespace(machineID);
33 
34  machineInfoCommand = std::make_unique<InfoCommand>(*this, "machine_info");
35  machineInfoCommand->setAllowedInEmptyMachine(true);
36 
37  msxEventDistributor.registerEventListener(*this);
38 }
39 
41 {
42  msxEventDistributor.unregisterEventListener(*this);
43 
44  machineInfoCommand.reset();
45 
46  #ifndef NDEBUG
47  for (auto* c : commandMap) {
48  std::cout << "Command not unregistered: " << c->getName() << '\n';
49  }
50  for (auto* s : settings) {
51  std::cout << "Setting not unregistered: " << s->getFullName() << '\n';
52  }
53  assert(commandMap.empty());
54  assert(settings.empty());
55  #endif
56 
57  globalCommandController.getInterpreter().deleteNamespace(machineID);
58 }
59 
60 string MSXCommandController::getFullName(string_view name)
61 {
62  return strCat(machineID, name);
63 }
64 
65 void MSXCommandController::registerCommand(Command& command, const string& str)
66 {
67  assert(!hasCommand(str));
68  assert(command.getName() == str);
69  commandMap.insert_noDuplicateCheck(&command);
70 
71  string fullname = getFullName(str);
72  globalCommandController.registerCommand(command, fullname);
73  globalCommandController.registerProxyCommand(str);
74 
75  command.setAllowedInEmptyMachine(false);
76 }
77 
79 {
80  assert(hasCommand(str));
81  assert(command.getName() == str);
82  commandMap.erase(str);
83 
84  globalCommandController.unregisterProxyCommand(str);
85  string fullname = getFullName(str);
86  globalCommandController.unregisterCommand(command, fullname);
87 }
88 
90  string_view str)
91 {
92  string fullname = getFullName(str);
93  globalCommandController.registerCompleter(completer, fullname);
94 }
95 
97  string_view str)
98 {
99  string fullname = getFullName(str);
100  globalCommandController.unregisterCompleter(completer, fullname);
101 }
102 
104 {
105  setting.setPrefix(machineID);
106 
107  settings.push_back(&setting);
108 
109  globalCommandController.registerProxySetting(setting);
110  globalCommandController.getSettingsManager().registerSetting(setting);
111  globalCommandController.getInterpreter().registerSetting(setting);
112 }
113 
115 {
116  move_pop_back(settings, rfind_unguarded(settings, &setting));
117 
118  globalCommandController.unregisterProxySetting(setting);
119  globalCommandController.getInterpreter().unregisterSetting(setting);
120  globalCommandController.getSettingsManager().unregisterSetting(setting);
121 }
122 
124 {
125  auto it = commandMap.find(name);
126  return (it != end(commandMap)) ? *it : nullptr;
127 }
128 
130 {
131  return findCommand(command) != nullptr;
132 }
133 
135  CliConnection* connection)
136 {
137  return globalCommandController.executeCommand(command, connection);
138 }
139 
141 {
142  return motherboard.getMSXCliComm();
143 }
144 
146 {
147  return globalCommandController.getInterpreter();
148 }
149 
150 void MSXCommandController::signalMSXEvent(
151  const std::shared_ptr<const Event>& event, EmuTime::param /*time*/)
152 {
153  if (event->getType() != OPENMSX_MACHINE_ACTIVATED) return;
154 
155  // simple way to synchronize proxy settings
156  for (auto* s : settings) {
157  try {
159  s->getFullNameObj(), s->getValue());
160  } catch (MSXException&) {
161  // ignore
162  }
163  }
164 }
165 
167 {
168  return reactor.getMotherBoard() == &motherboard;
169 }
170 
172 {
173  const auto& fromPrefix = from.getPrefix();
174  auto& manager = globalCommandController.getSettingsManager();
175  for (auto* s : settings) {
176  if (auto* fromSetting = manager.findSetting(fromPrefix, s->getBaseName())) {
177  if (!fromSetting->needTransfer()) continue;
178  try {
180  s->getFullNameObj(), fromSetting->getValue());
181  } catch (MSXException&) {
182  // ignore
183  }
184  }
185  }
186 }
187 
188 } // 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:64
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 unregisterSetting(BaseSetting &setting)
void deleteNamespace(const std::string &name)
Delete the global namespace with given name.
Definition: Interpreter.cc:436
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 unregisterCommand(Command &command, string_view str) override
void unregisterCompleter(CommandCompleter &completer, string_view str) override
void move_pop_back(VECTOR &v, typename VECTOR::iterator it)
Erase the pointed to element from the given vector.
Definition: stl.hh:191
const std::string & getName() const
Definition: Completer.hh:19
MSXMotherBoard * getMotherBoard() const
Definition: Reactor.cc:342
void registerCompleter(CommandCompleter &completer, string_view str) override
(Un)register a command completer, used to complete build-in Tcl cmds
void registerCommand(Command &command, const std::string &str) override
(Un)register a command
void unregisterProxyCommand(string_view name)
Interpreter & getInterpreter() override
const std::string & getPrefix() const
bool hasCommand(string_view command) const override
Does a command with this name already exist?
void registerSetting(BaseSetting &setting)
void setAllowedInEmptyMachine(bool value)
Definition: Command.hh:64
void unregisterEventListener(MSXEventListener &listener)
Unregisters a previously registered event listener.
void unregisterCommand(Command &command, string_view str) override
void registerCompleter(CommandCompleter &completer, string_view str) override
(Un)register a command completer, used to complete build-in Tcl cmds
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
This class implements a (close approximation) of the std::string_view class.
Definition: string_view.hh:16
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.
void setPrefix(string_view prefix)
Set a machine specific prefix.
Definition: Setting.hh:39
std::string strCat(Ts &&...ts)
Definition: strCat.hh:577
Command * findCommand(string_view name) const
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:166
void registerSetting(BaseSetting &variable)
Definition: Interpreter.cc:261
void unregisterCompleter(CommandCompleter &completer, string_view str) override
TclObject executeCommand(const std::string &command, CliConnection *connection=nullptr) override
Execute the given command.
void unregisterSetting(BaseSetting &variable)
Definition: Interpreter.cc:313
auto end(const string_view &x)
Definition: string_view.hh:152