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