00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _cvcl__include__context_h_
00031 #define _cvcl__include__context_h_
00032
00033 #include <string>
00034 #include <vector>
00035 #include "debug.h"
00036
00037
00038 namespace CVCL {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 class Context;
00049 class ContextManager;
00050 class ContextNotifyObj;
00051 class ContextObj;
00052 class ContextObjChain;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 class Scope {
00067 friend class ContextObj;
00068 friend class ContextObjChain;
00069 friend class CDFlags;
00070
00071 Context* d_context;
00072
00073
00074 Scope* d_prevScope;
00075
00076
00077 int d_level;
00078
00079
00080
00081 ContextObjChain* d_restoreChain;
00082
00083
00084 std::vector<ContextObjChain*> d_deleted;
00085
00086
00087 bool d_delayDelete;
00088
00089
00090 void addToChain(ContextObjChain* obj);
00091
00092 public:
00093
00094 Scope(Context* context, Scope* prevScope = NULL);
00095
00096 ~Scope();
00097
00098
00099 Scope* prevScope() const { return d_prevScope; }
00100 int level(void) const { return d_level; }
00101 bool isCurrent(void) const;
00102 Scope* topScope() const;
00103
00104
00105 void restore(void);
00106 };
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 class ContextObjChain {
00121 friend class Scope;
00122 friend class ContextObj;
00123 friend class CDFlags;
00124 private:
00125
00126 ContextObjChain* d_restoreChainNext;
00127
00128
00129
00130
00131 ContextObjChain** d_restoreChainPrev;
00132
00133
00134 ContextObjChain* d_restore;
00135
00136
00137 ContextObj* d_data;
00138
00139
00140 ContextObj* d_master;
00141
00142
00143 ContextObjChain(ContextObj* data, ContextObj* master,
00144 ContextObjChain* restore);
00145
00146
00147 ContextObjChain* restore(void);
00148 public:
00149
00150 ~ContextObjChain();
00151 IF_DEBUG(std::string name() const;);
00152 };
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 class ContextObj {
00166 friend class Scope;
00167 friend class ContextObjChain;
00168 friend class CDFlags;
00169 private:
00170
00171 Scope* d_scope;
00172
00173
00174
00175 ContextObjChain* d_restore;
00176
00177 IF_DEBUG(std::string d_name);
00178 IF_DEBUG(bool d_active);
00179
00180
00181 void update(int scope = -1);
00182
00183 protected:
00184
00185 ContextObj(const ContextObj& co);
00186
00187 ContextObj& operator=(const ContextObj& co);
00188
00189
00190 virtual ContextObj* makeCopy(void) = 0;
00191
00192
00193 virtual void restoreData(ContextObj* data) {
00194 FatalAssert(false,
00195 "ContextObj::restoreData(): call in the base abstract class");
00196 }
00197
00198
00199 virtual void setNull(void) = 0;
00200
00201
00202 IF_DEBUG(virtual std::string name() const { return d_name; });
00203
00204 public:
00205
00206
00207
00208
00209
00210
00211
00212
00213 ContextObj(Context* context, bool atBottomScope = true);
00214 virtual ~ContextObj();
00215
00216 int level() const { return (d_scope==NULL)? 0 : d_scope->level(); }
00217 bool isCurrent(int scope = -1) const {
00218 if(scope >= 0) return d_scope->level() == scope;
00219 else return d_scope->isCurrent();
00220 }
00221 void makeCurrent(int scope = -1) { if (!isCurrent(scope)) update(scope); }
00222 IF_DEBUG(void setName(const std::string& name) { d_name=name; });
00223 };
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 class Context {
00236
00237 ContextManager* d_cm;
00238
00239
00240 std::string d_name;
00241
00242
00243 int d_id;
00244
00245
00246 Scope* d_topScope;
00247 Scope* d_bottomScope;
00248
00249
00250 std::vector<ContextNotifyObj*> d_notifyObjList;
00251
00252 public:
00253 Context(ContextManager* cm, const std::string& name, int id);
00254 ~Context();
00255
00256
00257 ContextManager* getCM() const { return d_cm; }
00258 const std::string& name() const { return d_name; }
00259 int id() const { return d_id; }
00260 Scope* topScope() const { return d_topScope; }
00261 Scope* bottomScope() const { return d_bottomScope; }
00262 int level() const { return d_topScope->level(); }
00263
00264
00265 void push() {
00266 d_topScope = new Scope(this, d_topScope);
00267 TRACE("context", "*** [context] Pushing scope to level ", level(), " {");
00268 IF_DEBUG(DebugCounter maxLevel(debugger.counter("max scope level")));
00269 IF_DEBUG(if(maxLevel<level()) maxLevel=level());
00270 }
00271 void pop();
00272 void popto(int toLevel);
00273 void addNotifyObj(ContextNotifyObj* obj) { d_notifyObjList.push_back(obj); }
00274 void deleteNotifyObj(ContextNotifyObj* obj);
00275 };
00276
00277
00278 inline bool Scope::isCurrent(void) const
00279 { return this == d_context->topScope(); }
00280
00281 inline Scope* Scope::topScope() const { return d_context->topScope(); }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 class ContextManager {
00293 Context* d_curContext;
00294 std::vector<Context*> d_contexts;
00295
00296 public:
00297 ContextManager();
00298 ~ContextManager();
00299
00300 void push() { d_curContext->push(); }
00301 void pop() { d_curContext->pop(); }
00302 void popto(int toLevel) { d_curContext->popto(toLevel); }
00303 int scopeLevel() { return d_curContext->level(); }
00304 Context* createContext(const std::string& name="");
00305 Context* getCurrentContext() { return d_curContext; }
00306 Context* switchContext(Context* context);
00307 };
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 class ContextNotifyObj {
00322 friend class Context;
00323 protected:
00324 Context* d_context;
00325 public:
00326 ContextNotifyObj(Context* context): d_context(context)
00327 { context->addNotifyObj(this); }
00328 virtual ~ContextNotifyObj() {
00329
00330
00331
00332 if(d_context!=NULL) d_context->deleteNotifyObj(this);
00333 }
00334 virtual void notifyPre(void) {}
00335 virtual void notify(void) {}
00336 };
00337
00338
00339
00340 }
00341
00342 #endif