Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
command-impl.hpp
Go to the documentation of this file.
1 /*
2  COMMAND-IMPL.hpp - Proc-Layer command implementation (top level)
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 
42 #ifndef CONTROL_COMMAND_IMPL_H
43 #define CONTROL_COMMAND_IMPL_H
44 
45 #include "proc/control/command.hpp"
48 #include "lib/format-string.hpp"
49 #include "lib/nocopy.hpp"
50 
51 #include <memory>
52 #include <functional>
53 
54 
55 namespace proc {
56 namespace control {
57 
58  using util::_Fmt;
59  using std::function;
60  using std::shared_ptr;
61 
62 
63 
81  {
84 
86 
88 
89 
90  template<typename ARG>
91  struct _Type
92  {
93  typedef typename ARG::SIG_op SIG_op;
94  typedef typename ARG::SIG_cap SIG_cap;
95  typedef typename ARG::SIG_undo SIG_undo;
96 
97  typedef function<SIG_op> Func_op;
98  typedef function<SIG_cap> Func_cap;
99  typedef function<SIG_undo> Func_undo;
100  };
101 #define _TY(_ID_) typename _Type<ARG>::_ID_
102 
103  public:
109  template<typename ARG>
110  CommandImpl (shared_ptr<ARG> pStorageHolder
111  ,_TY (Func_op) const& operFunctor
112  ,_TY (Func_cap) const& captFunctor
113  ,_TY (Func_undo) const& undoFunctor
114  )
115  : do_(operFunctor)
116  , undo_(pStorageHolder->tie (undoFunctor, captFunctor))
117  , pClo_(pStorageHolder)
118  , defaultPatt_(HandlingPattern::defaultID())
119  { }
120 
121 #undef _TY
122 
123 
124  ~CommandImpl();
125 
126 
138  ,UndoMutation const& newUndo
139  ,shared_ptr<CmdClosure> const& newClosure)
140  : do_{orig.do_}
141  , undo_{newUndo}
142  , pClo_{newClosure}
143  , defaultPatt_{orig.defaultPatt_}
144  , cmdID{orig.cmdID}
145  { }
146 
147  explicit operator bool() const { return isValid(); }
148 
149 
154 
155 
165  void
167  {
168  ASSERT (pClo_);
169  pClo_->accept(visitor);
170  }
171 
172 
173  public: /* === implementation of command functionality === */
174 
175  void
177  {
178  pClo_->bindArguments (args);
179  }
180 
181  void
182  setArguments (lib::diff::Rec const& paramData)
183  {
184  pClo_->bindArguments (paramData);
185  }
186 
187  void
189  {
190  pClo_->unbindArguments();
191  }
192 
193  void invokeOperation() { do_(*pClo_); }
194  void invokeCapture() { undo_.captureState(*pClo_); }
195  void invokeUndo() { undo_(*pClo_); }
196 
197 
198 
200 
201  PattID
203  {
204  return defaultPatt_;
205  }
206 
209  PattID
210  setHandlingPattern (PattID newID)
211  {
212  PattID currID = defaultPatt_;
213  defaultPatt_ = newID;
214  return currID;
215  }
216 
217 
218 
219  /* === diagnostics === */
220 
221  bool
222  isValid() const
223  {
224  return bool(pClo_)
225  and HandlingPattern::get(defaultPatt_).isValid();
226  }
227 
228  bool
229  canExec() const
230  {
231  return isValid()
232  and pClo_->isValid();
233  }
234 
235  bool
236  canUndo() const
237  {
238  return isValid() and pClo_->isCaptured();
239  }
240 
241  operator string() const
242  {
243  return _Fmt("Cmd|valid:%s, exec:%s, undo:%s |%s")
244  % isValid()
245  % canExec()
246  % canUndo()
247  % (pClo_? string(*pClo_) : util::FAILURE_INDICATOR);
248  }
249 
250 
251 
252  friend bool
253  operator== (CommandImpl const& ci1, CommandImpl const& ci2)
254  {
255  return (ci1.do_ == ci2.do_)
256 // and (ci1.undo_ == ci2.undo_) // causes failure regularly, due to the missing equality on boost::function. See Ticket #294
257  and (ci1.defaultPatt_ == ci2.defaultPatt_)
258  and (ci1.canExec() == ci2.canExec())
259  and (ci1.canUndo() == ci2.canUndo())
260  and (ci1.pClo_->equals(*ci2.pClo_))
261  ;
262  }
263 
264  friend bool
265  operator!= (CommandImpl const& ci1, CommandImpl const& ci2)
266  {
267  return not (ci1==ci2);
268  }
269  };
270 
271 
272 
273 
274 
275 }} // namespace proc::control
276 #endif
Unspecific command functor for implementing Proc-Layer Command.
friend bool operator!=(CommandImpl const &ci1, CommandImpl const &ci2)
function< SIG_undo > Func_undo
bool canUndo() const
< state check: has undo state been captured?
PattID setHandlingPattern(PattID newID)
define a handling pattern to be used by default
static HandlingPattern const & get(ID id)
retrieve the pre-configured pattern
Core of a Proc-Layer command: functor containing the operation to be executed.
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
HandlingPattern::ID defaultPatt_
CommandImpl(shared_ptr< ARG > pStorageHolder, _TY(Func_op) const &operFunctor, _TY(Func_cap) const &captFunctor, _TY(Func_undo) const &undoFunctor)
build a new implementation frame, and do the initial wiring.
Front-end for printf-style string template interpolation.
Symbol cmdID
human-readable marker for diagnostics, will be (re)assigned when activating this CommandImpl ...
A front-end for using printf-style formatting.
void prepareClone(CommandImplCloneBuilder &visitor) const
assist with building a clone copy of this CommandImpl.
bool canExec() const
< state check: sufficiently defined to be invoked
Token or Atom with distinct identity.
Definition: symbol.hpp:116
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Proc-Layer Command implementation.
shared_ptr< CmdClosure > pClo_
PattID getDefaultHandlingPattern() const
Proc-Layer command frontend.
Visitor to support creating a CommandImpl clone.
Interface: Operation Skeleton how to invoke or undo a command.
Mutation & captureState(CmdClosure &clo)
void setArguments(Arguments &args)
friend bool operator==(CommandImpl const &ci1, CommandImpl const &ci2)
A closure enabling self-contained execution of commands within the ProcDispatcher.
void setArguments(lib::diff::Rec const &paramData)
Proc-Layer implementation namespace root.
Definition: id-scheme.hpp:63
const string FAILURE_INDICATOR
Definition: meta/util.hpp:243
bool isValid() const
< validity self-check: is basically usable.
CommandImpl(CommandImpl const &orig, UndoMutation const &newUndo, shared_ptr< CmdClosure > const &newClosure)
virtual bool isValid() const =0
object-like record of data.
Definition: record.hpp:143
#define _TY(_ID_)
HandlingPattern::ID PattID
Specialised version of the command Mutation functor, used to implement the UNDO functionality.