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