Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
command.hpp
Go to the documentation of this file.
1 /*
2  COMMAND.hpp - Key abstraction for proc/edit operations and UNDO management
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
68 #ifndef CONTROL_COMMAND_H
69 #define CONTROL_COMMAND_H
70 
71 #include "lib/error.hpp"
72 #include "lib/symbol.hpp"
73 #include "proc/common.hpp"
78 #include "lib/diff/gen-node.hpp"
79 #include "lib/handle.hpp"
80 
81 #include <string>
82 
83 
84 
85 
86 namespace proc {
87 namespace control {
88 
89  using std::string;
90  using lib::Symbol;
91  using std::shared_ptr;
92  using lib::meta::Tuple;
93  using lib::meta::Types;
94 
95 
96  LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS);
97  LUMIERA_ERROR_DECLARE (INVALID_COMMAND);
98  LUMIERA_ERROR_DECLARE (DUPLICATE_COMMAND);
99  LUMIERA_ERROR_DECLARE (INVALID_ARGUMENTS);
100 
101 
102 
103  typedef void* FuncPtr;
104 
105  class CommandDef;
106  class CommandImpl;
107 
108 
125  class Command
126  : public AcceptAnyBinding<Command // accepts arbitrary bind(..) calls (with runtime check)
127  , Command& // (return value of bind() functions is *this)
128  , lib::Handle<CommandImpl> // actually implemented as ref counting Handle
129  > //
130  {
132 
133  public:
134  /* === command registry === */
135  static Command get (Symbol cmdID);
136  static bool remove (Symbol cmdID);
137 
139  Command storeDef (Symbol newCmdID) const;
140  Command newInstance () const;
141 
142  static Command maybeGetNewInstance (Symbol cmdID);
143 
144 
145  Command (Symbol cmdID) { *this = get (cmdID); }
146  Command() { }
147  ~Command();
148 
149  // default copy acceptable
150  Command (Command &&) = default;
151  Command (Command const&) = default;
152  Command& operator= (Command &&) = default;
153  Command& operator= (Command const&) = default;
154 
155 
156 
157  /* === command lifecycle === */
158 
159  template<typename...TYPES>
160  Command& bindArg (std::tuple<TYPES...> const&);
161 
162  Command& bindArg (lib::diff::Rec const&);
163 
164  Command& unbind();
165 
166 
168  ExecResult exec () ;
169  ExecResult undo () ;
170 
171 
176  ExecResult exec (HandlingPattern const& execPattern);
178 
179  ExecResult undo (HandlingPattern const& execPattern);
181 
183  ExecResult execSync ();
184 
187 
191 
192 
193 
194  /* === diagnostics === */
195 
196  static size_t definition_count();
197  static size_t instance_count();
198 
199  bool canExec() const;
200  bool canUndo() const;
201 
202  static bool defined (Symbol cmdID);
203  static bool canExec (Symbol cmdID);
204  static bool canUndo (Symbol cmdID);
205 
206  void duplicate_detected (Symbol) const;
207 
208  Symbol getID() const noexcept;
209  bool isAnonymous() const;
210 
211  operator string() const;
212  friend bool operator== (Command const&, Command const&);
213  friend bool operator< (Command const&, Command const&);
214 
215 
216  protected:
217  static Command fetchDef (Symbol cmdID);
218  void activate (shared_ptr<CommandImpl> &&, Symbol cmdID =0);
219 
220  friend class CommandDef; //...invoking those two functions during definition stage
221 
222 
223  private:
224  void setArguments (Arguments&);
225  void setArguments (lib::diff::Rec const&);
226  static bool equivalentImpl (Command const&, Command const&);
227  };
228 
229 
230 
231 
232 
233  inline ExecResult
234  Command::operator() ()
235  {
236  return exec (getDefaultHandlingPattern());
237  }
238 
239  inline ExecResult
241  {
242  return exec (getDefaultHandlingPattern());
243  }
244 
245  inline ExecResult
247  {
248  return undo (getDefaultHandlingPattern());
249  }
250 
251 
252  template<typename...TYPES>
253  inline Command&
254  Command::bindArg (std::tuple<TYPES...> const& tuple)
255  {
256  TypedArguments<std::tuple<TYPES...>> args(tuple);
257  this->setArguments (args);
258  return *this;
259  }
260 
261 
262  inline Command&
263  Command::bindArg (lib::diff::Rec const& paramData)
264  {
265  this->setArguments (paramData);
266  return *this;
267  }
268 
269 
270 
271 
272  /* == state predicate shortcuts == */
273 
274  inline bool
276  {
277  return fetchDef(cmdID).isValid();
278  }
279 
280 
281 #define _FAILSAFE_COMMAND_QUERY(_ID_, _QUERY_) \
282  try \
283  { \
284  return Command::get(_ID_)._QUERY_; \
285  } \
286  catch(lumiera::error::Invalid&) \
287  { \
288  lumiera_error(); /* ignore errorstate */ \
289  return false; \
290  }
291 
292 
293  inline bool
295  {
296  _FAILSAFE_COMMAND_QUERY (cmdID, canExec() );
297  }
298 
299 
300  inline bool
302  {
303  _FAILSAFE_COMMAND_QUERY (cmdID, canUndo() );
304  }
305 
306 #undef _FAILSAFE_COMMAND_QUERY
307 
308 
309 
310 
311  inline bool
312  operator== (Command const& c1, Command const& c2)
313  {
314  return (!c1 && !c2)
315  || ( c1 && c2 && ( &c1.impl() == &c2.impl()
316  || Command::equivalentImpl (c1,c2)
317  ));
318  }
319 
320  inline bool
321  operator!= (Command const& c1, Command const& c2)
322  {
323  return not (c1 == c2);
324  }
325 
327  inline bool
328  operator< (Command const& c1, Command const& c2)
329  {
330  return (!c1 && c2)
331  || ( c1 && c2 && (&c1.impl() < &c2.impl()));
332  }
333 
334 
335 
336 
337 }} // namespace proc::control
338 #endif
LUMIERA_ERROR_DECLARE(INVALID_ARGUMENTS)
Arguments provided for binding doesn't match stored command function parameters.
Record< GenNode > Rec
Definition: gen-node.hpp:133
ExecResult exec()
Definition: command.hpp:240
static size_t definition_count()
Definition: command.cpp:296
bool isValid() const
Definition: handle.hpp:104
void setArguments(Arguments &)
Definition: command.cpp:258
void duplicate_detected(Symbol) const
Definition: command.cpp:237
Implementation helper to bind Proc-Layer commands with arbitrary argument tuples. ...
Mixin-templates providing arbitrary function call operators and argument binding functions.
Command(Symbol cmdID)
Definition: command.hpp:145
static bool defined(Symbol cmdID)
Definition: command.hpp:275
HandlingPattern::ID setHandlingPattern(HandlingPattern::ID)
define a handling pattern to be used by default
Definition: command.cpp:479
Helper class used solely for defining a Command-Object.
typename BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
Helper Template for control::Command, mix-in complete set of bind(...) functions. ...
Command newInstance() const
create independent (anonymous) clone copy of this command
Definition: command.cpp:207
Implementation namespace for support and library code.
Metaprogramming with tuples-of-types and the std::tuple record.
Basic set of definitions and includes commonly used together.
bool canUndo() const
Definition: command.cpp:365
Command & bindArg(std::tuple< TYPES...> const &)
Definition: command.hpp:254
void * FuncPtr
Definition: command.hpp:103
Command()
undefined command
Definition: command.hpp:146
Symbol getID() const noexcept
Definition: command.cpp:380
Token or Atom with distinct identity.
Definition: symbol.hpp:116
IMP & impl() const
Definition: handle.hpp:149
Proc-Layer Command implementation.
Marker types to indicate a literal string and a Symbol.
bool isAnonymous() const
Definition: command.cpp:393
void activate(shared_ptr< CommandImpl > &&, Symbol cmdID=0)
Definition: command.cpp:169
ExecResult operator()()
Definition: command.hpp:234
#define _FAILSAFE_COMMAND_QUERY(_ID_, _QUERY_)
Definition: command.hpp:281
Command & operator=(Command &&)=default
Generic building block for tree shaped (meta)data structures.
friend bool operator<(Command const &, Command const &)
allow for sets and associative containers
Definition: command.hpp:328
static size_t instance_count()
Definition: command.cpp:305
Command & unbind()
discard any argument data previously bound.
Definition: command.cpp:286
Result (Status) of command execution.
static bool equivalentImpl(Command const &, Command const &)
Definition: command.cpp:373
Pre-defined command execution skeletons.
bool canExec() const
Definition: command.cpp:357
Interface: Operation Skeleton how to invoke or undo a command.
Lumiera error handling (C++ interface).
lib::Handle< CommandImpl > _Handle
Definition: command.hpp:131
static Command fetchDef(Symbol cmdID)
Definition: command.cpp:157
Handle object representing a single Command instance to be used by client code.
Definition: command.hpp:125
A generic opaque handle to an implementation entity, including lifecycle management.
static Command maybeGetNewInstance(Symbol cmdID)
try to access an existing command definition and immediately create a new clone copy by calling newIn...
Definition: command.cpp:147
Command storeDef(Symbol newCmdID) const
create a clone definition
Definition: command.cpp:190
Proc-Layer implementation namespace root.
Definition: id-scheme.hpp:63
object-like record of data.
Definition: record.hpp:143
friend bool operator==(Command const &, Command const &)
Definition: command.hpp:312
bool operator!=(Command const &c1, Command const &c2)
Definition: command.hpp:321
ExecResult undo()
Definition: command.hpp:246
ExecResult execSync()
invoke using a default "synchronous" execution pattern
Definition: command.cpp:464
HandlingPattern::ID getDefaultHandlingPattern() const
Definition: command.cpp:471