00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00053 #ifndef MOBJECT_BUILDER_TOOL_H
00054 #define MOBJECT_BUILDER_TOOL_H
00055
00056 #include "common/visitor.hpp"
00057 #include "common/wrapperptr.hpp"
00058
00059 #include "common/p.hpp"
00060 #include "proc/mobject/placement.hpp"
00061 #include "proc/mobject/explicitplacement.hpp"
00062
00063
00064 namespace mobject {
00065
00066 class Buildable;
00067
00068 namespace builder {
00069
00070 using lumiera::P;
00071
00077 template<class RET>
00078 class InvokeCatchAllFunction
00079 {
00080 protected:
00081 virtual ~InvokeCatchAllFunction() {}
00082 public:
00083 virtual RET onUnknown (Buildable& target) = 0;
00084 };
00085
00086
00087
00107 class BuilderTool
00108 : public lumiera::visitor::Tool<void, InvokeCatchAllFunction>
00109 {
00110 lumiera::WrapperPtr currentWrapper_;
00111
00112 public:
00113
00114 template<template<class> class WRA, class TAR>
00115 void rememberWrapper (WRA<TAR>* ptr_toWrappedTarget)
00116 {
00117 currentWrapper_ = ptr_toWrappedTarget;
00118 }
00119
00120 void forgetWrapper ()
00121 {
00122 currentWrapper_.reset();
00123 }
00124
00125
00126 protected:
00127
00128 template<class TAR>
00129 Placement<TAR>&
00130 getPlacement ()
00131 {
00132 Placement<TAR>* pPlacement = currentWrapper_.get<Placement<TAR>*>();
00133 ENSURE (pPlacement, "wrong target type when invoking %s", __PRETTY_FUNCTION__);
00134 return *pPlacement;
00135 }
00136
00137 ExplicitPlacement
00138 getExplicitPlacement ()
00139 {
00140 return getPlacement<MObject>().resolve();
00141 }
00142
00143 template<class TAR>
00144 lumiera::P<TAR>
00145 getPtr ()
00146 {
00147 P<TAR>* pP = currentWrapper_.get<P<TAR>*>();
00148 ENSURE (pP, "wrong target type when invoking %s", __PRETTY_FUNCTION__);
00149 return *pP;
00150 }
00151 };
00152
00153
00154
00159 template
00160 < class TOOLImpl,
00161 class TYPELIST
00162 >
00163 class Applicable
00164 : public lumiera::visitor::Applicable<TOOLImpl, TYPELIST, BuilderTool>
00165 { }
00166 ;
00167
00168 using lumiera::typelist::Types;
00169
00170 }
00171
00172
00173
00177 class Buildable : public lumiera::visitor::Visitable<builder::BuilderTool>
00178 { };
00179
00180
00181
00182
00183 namespace builder {
00184
00185 template<typename WRA>
00186 inline Buildable::ReturnType
00187 apply (BuilderTool& tool, WRA& wrappedTargetObj)
00188 {
00189 tool.rememberWrapper(&wrappedTargetObj);
00190 wrappedTargetObj->apply (tool);
00191 tool.forgetWrapper();
00192 }
00193
00194 }
00195
00196 }
00197 #endif