Fix some compilation errors on Mac OS X
[lsnes.git] / include / library / command.hpp
blobc8c3cbe9dedbef05b68582146f09096a8b759248
1 #ifndef _library_command__hpp__included__
2 #define _library_command__hpp__included__
4 #include <stdexcept>
5 #include <string>
6 #include <functional>
7 #include <set>
8 #include <map>
9 #include <list>
11 namespace command
13 class set;
14 class base;
15 class factory_base;
17 /**
18 * A set of commands.
20 class set
22 public:
23 /**
24 * Set add/drop listener.
26 class listener
28 public:
29 /**
30 * Dtor.
32 virtual ~listener();
33 /**
34 * New item in set.
36 virtual void create(set& s, const std::string& name, factory_base& cmd) = 0;
37 /**
38 * Deleted item from set.
40 virtual void destroy(set& s, const std::string& name) = 0;
41 /**
42 * Destroyed the entiere set.
44 virtual void kill(set& s) = 0;
46 /**
47 * Create a new set.
49 set() throw(std::bad_alloc);
50 /**
51 * Destroy a set.
53 ~set() throw();
54 /**
55 * Add a command to set.
57 void do_register(const std::string& name, factory_base& cmd) throw(std::bad_alloc);
58 /**
59 * Remove a command from set.
61 void do_unregister(const std::string& name, factory_base& cmd) throw(std::bad_alloc);
62 /**
63 * Add a notification callback and call ccb on all.
65 * Parameter listener: The listener to add.
67 void add_callback(listener& listener) throw(std::bad_alloc);
68 /**
69 * Drop a notification callback and call dcb on all.
71 * Parameter listener: The listener to drop.
73 void drop_callback(listener& listener) throw();
74 private:
75 char dummy;
78 /**
79 * A group of commands (with aliases).
81 class group
83 public:
84 /**
85 * Create a new command group. This also places some builtin commands in that new group.
87 group() throw(std::bad_alloc);
88 /**
89 * Destroy a group.
91 ~group() throw();
92 /**
93 * Look up and invoke a command. The command will undergo alias expansion and recursion checking.
95 * parameter cmd: Command to exeucte.
97 void invoke(const std::string& cmd) throw();
98 /**
99 * Look up and invoke a command. No alias expansion is performed, but recursion checking is.
101 * parameter cmd: Command to execute.
102 * parameter args: The parameters for command.
104 void invoke(const std::string& cmd, const std::string& args) throw();
106 * Get set of aliases.
108 std::set<std::string> get_aliases() throw(std::bad_alloc);
110 * Get alias
112 std::string get_alias_for(const std::string& aname) throw(std::bad_alloc);
114 * Set alias
116 void set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc);
118 * Is alias name valid.
120 bool valid_alias_name(const std::string& aname) throw(std::bad_alloc);
122 * Register a command.
124 void do_register(const std::string& name, base& cmd) throw(std::bad_alloc);
126 * Unregister a command.
128 void do_unregister(const std::string& name, base& cmd) throw(std::bad_alloc);
130 * Add all commands (including future ones) in given set.
132 void add_set(set& s) throw(std::bad_alloc);
134 * Drop a set of commands.
136 void drop_set(set& s) throw();
138 * Set the output stream.
140 void set_output(std::ostream& s);
142 * Set the OOM panic routine.
144 void set_oom_panic(void (*fn)());
145 private:
146 class listener : public set::listener
148 public:
149 listener(group& _grp);
150 ~listener();
151 void create(set& s, const std::string& name, factory_base& cmd);
152 void destroy(set& s, const std::string& name);
153 void kill(set& s);
154 private:
155 group& grp;
156 } _listener;
157 std::set<std::string> command_stack;
158 std::map<std::string, std::list<std::string>> aliases;
159 std::ostream* output;
160 void (*oom_panic_routine)();
161 base* builtin[1];
165 * A command.
167 class base
169 public:
171 * Register a new command.
173 * parameter group: The group command will be part of.
174 * parameter cmd: The command to register.
175 * parameter dynamic: Should the object be freed when its parent group dies?
176 * throws std::bad_alloc: Not enough memory.
178 base(group& group, const std::string& cmd, bool dynamic) throw(std::bad_alloc);
181 * Deregister a command.
183 virtual ~base() throw();
186 * Invoke a command.
188 * parameter arguments: Arguments to command.
189 * throws std::bad_alloc: Not enough memory.
190 * throws std::runtime_error: Command execution failed.
192 virtual void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error) = 0;
194 * Get short help for command.
196 virtual std::string get_short_help() throw(std::bad_alloc);
199 * Get long help for command.
201 virtual std::string get_long_help() throw(std::bad_alloc);
203 * Get name of command.
205 const std::string& get_name() { return commandname; }
207 * Notify that the parent group died.
209 * Note: Assumed to be called with global lock held.
211 void group_died() throw();
212 private:
213 base(const base&);
214 base& operator=(const base&);
215 std::string commandname;
216 group* in_group;
217 bool is_dynamic;
221 * A command factory.
223 class factory_base
225 public:
226 factory_base() throw() {}
228 * Register a new command.
230 * parameter _set: The set command will be part of.
231 * parameter cmd: The command to register.
232 * throws std::bad_alloc: Not enough memory.
234 void _factory_base(set& _set, const std::string& cmd) throw(std::bad_alloc);
236 * Destructor.
238 virtual ~factory_base() throw();
240 * Make a new command.
242 virtual base* make(group& grp) = 0;
244 * Notify that the parent set died.
246 * Note: Assumed to be called with global lock held.
248 void set_died() throw();
249 private:
250 factory_base(const factory_base&);
251 factory_base& operator=(const factory_base&);
252 std::string commandname;
253 set* in_set;
257 * Name, Description and help for command.
259 struct stub
262 * The command name.
264 const char* name;
266 * The short description.
268 const char* desc;
270 * The long help.
272 const char* help;
276 * Mandatory filename
278 struct arg_filename
281 * The filename itself.
283 std::string v;
285 * Return the filename.
287 * returns: The filename.
289 operator std::string() { return v; }
293 * Run command function helper.
295 * parameter fn: Function pointer to invoke.
296 * parameter a: The arguments to pass.
298 template<typename... args>
299 void invoke_fn(std::function<void(args... arguments)> fn, const std::string& a);
302 * Warp function pointer as command.
304 template<typename... args>
305 class _fnptr : public base
307 public:
309 * Create a new command.
311 * parameter group: The group command will be part of.
312 * parameter name: Name of the command
313 * parameter description Description for the command
314 * parameter help: Help for the command.
315 * parameter fn: Function to call on command.
316 * parameter dynamic: Should the object be freed when its parent group dies?
318 _fnptr(group& group, const std::string& name, const std::string& _description,
319 const std::string& _help, void (*_fn)(args... arguments), bool dynamic = false) throw(std::bad_alloc)
320 : base(group, name, dynamic)
322 shorthelp = _description;
323 help = _help;
324 fn = _fn;
327 * Create a new command.
329 * parameter _set: The set command will be part of.
330 * parameter name: Name of the command
331 * parameter fn: Function to call on command.
332 * parameter description Description&Help for the command
334 _fnptr(group& _group, stub _name, std::function<void(args... arguments)> _fn) throw(std::bad_alloc)
335 : base(_group, _name.name, false)
337 shorthelp = _name.desc;
338 help = _name.help;
339 fn = _fn;
342 * Destroy a commnad.
344 ~_fnptr() throw()
348 * Invoke a command.
350 * parameter a: Arguments to function.
352 void invoke(const std::string& a) throw(std::bad_alloc, std::runtime_error)
354 invoke_fn(fn, a);
357 * Get short description.
359 * returns: Description.
360 * throw std::bad_alloc: Not enough memory.
362 std::string get_short_help() throw(std::bad_alloc)
364 return shorthelp;
367 * Get long help.
369 * returns: help.
370 * throw std::bad_alloc: Not enough memory.
372 std::string get_long_help() throw(std::bad_alloc)
374 return help;
376 private:
377 std::function<void(args... arguments)> fn;
378 std::string shorthelp;
379 std::string help;
383 * Function pointer command factory.
385 template<typename... args>
386 class fnptr : public factory_base
388 public:
390 * Create a new command.
392 * parameter _set: The set command will be part of.
393 * parameter desc: Command descriptor.
394 * parameter fn: Function to call on command.
396 fnptr(set& _set, stub _name, void (*_fn)(args... arguments)) throw(std::bad_alloc)
398 shorthelp = _name.desc;
399 name = _name.name;
400 help = _name.help;
401 fn = _fn;
402 _factory_base(_set, name);
405 * Create a new command.
407 * parameter _set: The set command will be part of.
408 * parameter name: Name of the command
409 * parameter description Description for the command
410 * parameter help: Help for the command.
411 * parameter fn: Function to call on command.
413 fnptr(set& _set, const std::string& _name, const std::string& _description,
414 const std::string& _help, void (*_fn)(args... arguments)) throw(std::bad_alloc)
416 shorthelp = _description;
417 name = _name;
418 help = _help;
419 fn = _fn;
420 _factory_base(_set, name);
423 * Destroy a commnad.
425 ~fnptr() throw()
429 * Make a command.
431 base* make(group& grp) throw(std::bad_alloc)
433 return new _fnptr<args...>(grp, name, shorthelp, help, fn, true);
435 private:
436 void (*fn)(args... arguments);
437 std::string shorthelp;
438 std::string help;
439 std::string name;
443 * Generic byname factory.
445 template<typename T>
446 class byname_factory : public factory_base
448 public:
450 * Create a new factory.
452 byname_factory(set& s, const std::string& _name)
454 name = _name;
455 _factory_base(s, name);
458 * Destroy.
460 ~byname_factory() throw()
464 * Make a command.
466 base* make(group& grp) throw(std::bad_alloc)
468 return new T(grp, name);
470 private:
471 std::string name;
474 #endif