Lumiera  0.pre.03
»edit your freedom«
command-def.hpp
Go to the documentation of this file.
1 /*
2  COMMAND-DEF.hpp - defining and binding a Steam-Layer command
3 
4  Copyright (C)
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
44 #ifndef CONTROL_COMMAND_DEF_H
45 #define CONTROL_COMMAND_DEF_H
46 
47 #include "lib/error.hpp"
48 #include "lib/nocopy.hpp"
49 #include "include/logging.h"
50 #include "lib/symbol.hpp"
52 #include "steam/control/command-impl.hpp" // note: at command definition site we need to know the full type
57 #include "lib/meta/function.hpp"
58 #include "lib/meta/typelist.hpp"
61 #include "lib/util.hpp"
62 
63 #include <memory>
64 #include <functional>
65 
66 
67 
68 
69 namespace steam {
70 namespace control {
71 
72  using std::shared_ptr;
73  using std::function;
74  using std::bind;
75  using std::placeholders::_1;
76  using std::tuple_size;
77  using lib::Symbol;
78 
79  using lib::meta::_Fun;
80  using lib::meta::NullType;
81  using lib::meta::Types;
82  using lib::meta::TySeq;
83  using lib::meta::Tuple;
84 
85 
86 
87 
88  namespace stage {
89 
91  using Activation = function<Command&(ImplInstance &&)>;
92 
93 
94 
95 
96  template<typename SIG>
98  : AcceptArgumentBindingRet< Command&, SIG // Return type and Argument Signature of the \c bind(..) function
99  , CompletedDefinition<SIG> // target type (this class) providing the implementation \c bindArg(Tuple<..>)
100  >
101  {
102  Command& prototype_;
103 
104  using CmdArgs = typename _Fun<SIG>::Args;
105 
106  CompletedDefinition (Command& definedCommand)
107  : prototype_(definedCommand)
108  {
109  REQUIRE (prototype_);
111  TRACE (command_dbg, "Completed definition of %s.", cStr(prototype_));
112  }
113 
114 
115  typedef HandlingPattern::ID PattID;
116 
121  {
122  prototype_.setHandlingPattern(newID);
123  return *this;
124  }
125 
126 
130  Command&
131  bindArg (Tuple<CmdArgs> const& params)
132  {
133  return prototype_.bindArg(params);
134  }
135 
136 
140  operator Command ()
141  {
142  return prototype_;
143  }
144 
145  private:
150  void
152  {
153  if (0 == tuple_size<Tuple<CmdArgs>>::value )
154  prototype_.bindArg<> (std::tuple<>());
155  }
156  };
157 
158 
159 
160 
161 
162  template<typename SIG, typename MEM>
164  {
166  typedef typename CmdType::OperateSig CommandOperationSig;
167  typedef typename CmdType::UndoOp_Sig UndoOperationSig;
168  typedef typename CmdType::CaptureSig UndoCaptureSig;
169  typedef typename CmdType::CmdArgs CmdArgs;
170 
171  typedef function<CommandOperationSig> OperFunc;
172  typedef function<UndoOperationSig> UndoFunc;
173  typedef function<UndoCaptureSig> CaptFunc;
174 
175  Activation activatePrototype_;
176  OperFunc operFunctor_;
177  CaptFunc captFunctor_;
178  UndoFunc undoFunctor_;
179 
180 
181  UndoDefinition (Activation const& whenComplete,
182  OperFunc const& commandOperation,
183  CaptFunc const& undoCapOperation)
184  : activatePrototype_(whenComplete)
185  , operFunctor_(commandOperation)
186  , captFunctor_(undoCapOperation)
187  , undoFunctor_()
188  { }
189 
190 
192  undoOperation (UndoOperationSig how_to_Undo)
193  {
194  undoFunctor_ = UndoFunc (how_to_Undo);
195  REQUIRE (operFunctor_);
196  REQUIRE (undoFunctor_);
197  REQUIRE (captFunctor_);
198 
200  ImplInstance completedDef = registry.newCommandImpl(operFunctor_
201  ,captFunctor_
202  ,undoFunctor_);
203  return CompletedDefinition<SIG> {activatePrototype_(move (completedDef))};
204  }
205  };
206 
207 
208 
209 
212  template<typename U_SIG>
214  {
216  };
217 
218 
219 
220 
221 
222 
223  template<typename SIG>
225  {
226  Activation callback_;
227  function<SIG> operation_;
228 
229  BasicDefinition(Activation const& whenComplete, function<SIG> const& operation)
230  : callback_(whenComplete)
231  , operation_(operation)
232  { }
233 
234 
235  template<typename FUN2>
236  auto
237  captureUndo (FUN2 how_to_capture_UndoState)
238  {
239  using Sig2 = typename _Fun<FUN2>::Sig;
240  using UndoCapSig = typename UndoSignature<Sig2>::CaptureSig;
241  using SpecificUndoDefinition = typename BuildUndoDefType<UndoSignature<Sig2>>::Type;
242 
243  function<UndoCapSig> captureOperation (how_to_capture_UndoState);
244  return SpecificUndoDefinition (callback_, operation_, captureOperation);
245  }
246  };
247 
248  } // (END) namespace stage (definition process)
249 
250 
270  {
271  Symbol id_;
272  Command prototype_;
273 
274  using PImpl = stage::ImplInstance;
275  using Activation = stage::Activation;
276 
277  public:
278  CommandDef (Symbol cmdID)
279  : id_(cmdID)
280  , prototype_(Command::fetchDef(cmdID))
281  {
282  TRACE (command_dbg, "starting CommandDef('%s')...", cmdID.c() );
283  }
284 
285  ~CommandDef();
286 
287 
288 
289  template<typename FUN>
290  auto
291  operation (FUN operation_to_define)
292  {
293  using Sig = typename _Fun<FUN>::Sig;
294 
295  function<Sig> opera1 (operation_to_define);
296  Activation callback_when_defined = bind (&CommandDef::activate, this, _1);
297 
298  return stage::BasicDefinition<Sig>(callback_when_defined, opera1);
299  }
300 
301 
302  explicit operator bool() const { return isValid(); }
303 
304  bool isValid() const;
305 
306 
307  private:
311  Command& activate (PImpl && completedDef)
312  {
313  prototype_.activate (move (completedDef), id_);
314  ENSURE (prototype_);
315  return prototype_;
316  }
317  };
318 
319 
320 
321 
322 
323 }} // namespace steam::control
324 #endif
Helper class used solely for defining a Command-Object.
HandlingPattern::ID setHandlingPattern(HandlingPattern::ID)
define a handling pattern to be used by default
Definition: command.cpp:465
CompletedDefinition setHandlingPattern(PattID newID)
allow for defining the default execution pattern, which is used by Command::operator() ...
A template metaprogramming technique for manipulating collections of types.
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:59
typename BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
Core of a Steam-Layer command: functor containing the operation to be executed.
Mixin-templates providing arbitrary function call operators and argument binding functions.
shared_ptr< CommandImpl > newCommandImpl(function< SIG_OPER > &operFunctor, function< SIG_CAPT > &captFunctor, function< SIG_UNDO > &undoFunctor)
set up a new command implementation frame
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
Top level of the command implementation.
void activate(shared_ptr< CommandImpl > &&, Symbol cmdID=0)
Definition: command.cpp:162
Managing command definitions and the storage of individual command objects.
temporary workaround: alternative definition of "type sequence", already using variadic template para...
Helper for uniform access to function signature types.
Definition: function.hpp:99
This header is for including and configuring NoBug.
Registry managing command implementation objects (Singleton).
Steam-Layer implementation namespace root.
Metaprogramming with tuples-of-types and the std::tuple record.
Token or Atom with distinct identity.
Definition: symbol.hpp:117
Mix-Ins to allow or prohibit various degrees of copying and cloning.
type re-binding helper: create a suitable UndoDefinition type, based on the UndoSignature template in...
Metaprogramming tools for transforming functor types.
Marker types to indicate a literal string and a Symbol.
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Command & bindArg(Tuple< CmdArgs > const &params)
allow to bind immediately to a set of arguments.
Steam-Layer command frontend.
void maybeArm_if_zero_parameters()
Helper: automatically "bind" and make executable a command, for the case when the command operation t...
static Command fetchDef(Symbol cmdID)
Definition: command.cpp:150
Lumiera error handling (C++ interface).
Handle object representing a single Command instance to be used by client code.
Definition: command.hpp:115
Command & activate(PImpl &&completedDef)
callback from completed command definition stage: "arm up" the command handle object and register it ...
Metaprogramming helper for building Command function signatures.
Metaprogramming helpers for deriving the precise function signatures necessary to implement a given c...
Metaprogramming: Helpers for manipulating lists-of-types.
static lib::Depend< CommandRegistry > instance
storage for the singleton factory used to access CommandRegistry
Variation of AcceptArgumentBinding, allowing to control the return type of the generated bind(...