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) 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 
53 #ifndef CONTROL_COMMAND_DEF_H
54 #define CONTROL_COMMAND_DEF_H
55 
56 #include "lib/error.hpp"
57 #include "lib/nocopy.hpp"
58 #include "include/logging.h"
59 #include "lib/symbol.hpp"
61 #include "steam/control/command-impl.hpp" // note: at command definition site we need to know the full type
66 #include "lib/meta/function.hpp"
67 #include "lib/meta/typelist.hpp"
70 #include "lib/util.hpp"
71 
72 #include <memory>
73 #include <functional>
74 
75 
76 
77 
78 namespace steam {
79 namespace control {
80 
81  using std::shared_ptr;
82  using std::function;
83  using std::bind;
84  using std::placeholders::_1;
85  using std::tuple_size;
86  using lib::Symbol;
87 
88  using lib::meta::_Fun;
89  using lib::meta::NullType;
90  using lib::meta::Types;
91  using lib::meta::TySeq;
92  using lib::meta::Tuple;
93 
94 
95 
96 
97  namespace stage {
98 
100  using Activation = function<Command&(ImplInstance &&)>;
101 
102 
103 
104 
105  template<typename SIG>
107  : AcceptArgumentBindingRet< Command&, SIG // Return type and Argument Signature of the \c bind(..) function
108  , CompletedDefinition<SIG> // target type (this class) providing the implementation \c bindArg(Tuple<..>)
109  >
110  {
111  Command& prototype_;
112 
113  using CmdArgs = typename _Fun<SIG>::Args;
114 
115  CompletedDefinition (Command& definedCommand)
116  : prototype_(definedCommand)
117  {
118  REQUIRE (prototype_);
120  TRACE (command_dbg, "Completed definition of %s.", cStr(prototype_));
121  }
122 
123 
124  typedef HandlingPattern::ID PattID;
125 
130  {
131  prototype_.setHandlingPattern(newID);
132  return *this;
133  }
134 
135 
139  Command&
140  bindArg (Tuple<CmdArgs> const& params)
141  {
142  return prototype_.bindArg(params);
143  }
144 
145 
149  operator Command ()
150  {
151  return prototype_;
152  }
153 
154  private:
159  void
161  {
162  if (0 == tuple_size<Tuple<CmdArgs>>::value )
163  prototype_.bindArg<> (std::tuple<>());
164  }
165  };
166 
167 
168 
169 
170 
171  template<typename SIG, typename MEM>
173  {
175  typedef typename CmdType::OperateSig CommandOperationSig;
176  typedef typename CmdType::UndoOp_Sig UndoOperationSig;
177  typedef typename CmdType::CaptureSig UndoCaptureSig;
178  typedef typename CmdType::CmdArgs CmdArgs;
179 
180  typedef function<CommandOperationSig> OperFunc;
181  typedef function<UndoOperationSig> UndoFunc;
182  typedef function<UndoCaptureSig> CaptFunc;
183 
184  Activation activatePrototype_;
185  OperFunc operFunctor_;
186  CaptFunc captFunctor_;
187  UndoFunc undoFunctor_;
188 
189 
190  UndoDefinition (Activation const& whenComplete,
191  OperFunc const& commandOperation,
192  CaptFunc const& undoCapOperation)
193  : activatePrototype_(whenComplete)
194  , operFunctor_(commandOperation)
195  , captFunctor_(undoCapOperation)
196  , undoFunctor_()
197  { }
198 
199 
201  undoOperation (UndoOperationSig how_to_Undo)
202  {
203  undoFunctor_ = UndoFunc (how_to_Undo);
204  REQUIRE (operFunctor_);
205  REQUIRE (undoFunctor_);
206  REQUIRE (captFunctor_);
207 
209  ImplInstance completedDef = registry.newCommandImpl(operFunctor_
210  ,captFunctor_
211  ,undoFunctor_);
212  return CompletedDefinition<SIG> {activatePrototype_(move (completedDef))};
213  }
214  };
215 
216 
217 
218 
221  template<typename U_SIG>
223  {
225  };
226 
227 
228 
229 
230 
231 
232  template<typename SIG>
234  {
235  Activation callback_;
236  function<SIG> operation_;
237 
238  BasicDefinition(Activation const& whenComplete, function<SIG> const& operation)
239  : callback_(whenComplete)
240  , operation_(operation)
241  { }
242 
243 
244  template<typename FUN2>
245  auto
246  captureUndo (FUN2 how_to_capture_UndoState)
247  {
248  using Sig2 = typename _Fun<FUN2>::Sig;
249  using UndoCapSig = typename UndoSignature<Sig2>::CaptureSig;
250  using SpecificUndoDefinition = typename BuildUndoDefType<UndoSignature<Sig2>>::Type;
251 
252  function<UndoCapSig> captureOperation (how_to_capture_UndoState);
253  return SpecificUndoDefinition (callback_, operation_, captureOperation);
254  }
255  };
256 
257  } // (END) namespace stage (definition process)
258 
259 
279  {
280  Symbol id_;
281  Command prototype_;
282 
283  using PImpl = stage::ImplInstance;
284  using Activation = stage::Activation;
285 
286  public:
287  CommandDef (Symbol cmdID)
288  : id_(cmdID)
289  , prototype_(Command::fetchDef(cmdID))
290  {
291  TRACE (command_dbg, "starting CommandDef('%s')...", cmdID.c() );
292  }
293 
294  ~CommandDef();
295 
296 
297 
298  template<typename FUN>
299  auto
300  operation (FUN operation_to_define)
301  {
302  using Sig = typename _Fun<FUN>::Sig;
303 
304  function<Sig> opera1 (operation_to_define);
305  Activation callback_when_defined = bind (&CommandDef::activate, this, _1);
306 
307  return stage::BasicDefinition<Sig>(callback_when_defined, opera1);
308  }
309 
310 
311  explicit operator bool() const { return isValid(); }
312 
313  bool isValid() const;
314 
315 
316  private:
320  Command& activate (PImpl && completedDef)
321  {
322  prototype_.activate (move (completedDef), id_);
323  ENSURE (prototype_);
324  return prototype_;
325  }
326  };
327 
328 
329 
330 
331 
332 }} // namespace steam::control
333 #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:474
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:68
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:46
Top level of the command implementation.
void activate(shared_ptr< CommandImpl > &&, Symbol cmdID=0)
Definition: command.cpp:171
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:108
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:126
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:46
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:159
Lumiera error handling (C++ interface).
Handle object representing a single Command instance to be used by client code.
Definition: command.hpp:124
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(...