00001 #ifndef FLOWEQUATIONS_H 00002 #define FLOWEQUATIONS_H 00003 00004 #include <vector> 00005 00006 class Constraint; 00007 00008 class Variable { 00009 std::vector<Constraint*> users; // Constraints that use the value of this variable 00010 void addUser(Constraint* c) { 00011 users.push_back(c); 00012 } 00013 00014 protected: 00015 Variable() 00016 : users() 00017 {} 00018 // After updating the value of the variable (done in a subclass-specific 00019 // way), this function will update all downstream variables, cycling as 00020 // necessary to reach a fixpoint 00021 void pushChanges() const; 00022 00023 public: 00024 virtual ~Variable() {} 00025 friend class Constraint; 00026 }; 00027 00028 class Constraint { 00029 bool needsToRun; 00030 bool getNeedsToRun() const { 00031 return needsToRun; 00032 } 00033 void setNeedsToRun() { 00034 needsToRun = true; 00035 } 00036 void resetNeedsToRun() { 00037 needsToRun = false; 00038 } 00039 void runFull() { // Does changed checking and updating 00040 if (!getNeedsToRun()) 00041 return; 00042 resetNeedsToRun(); 00043 run(); 00044 } 00045 00046 protected: 00047 Constraint() 00048 : needsToRun(true) 00049 {} 00050 00051 virtual void run() const = 0; 00052 virtual void markDependencies() = 0; 00053 void addDependency(Variable* var) { 00054 var->addUser(this); 00055 } 00056 00057 public: 00058 void activate() { 00059 markDependencies(); 00060 runFull(); 00061 } 00062 00063 virtual ~Constraint() {} 00064 friend class Variable; 00065 friend class FlowEquationSet; 00066 }; 00067 00068 inline void 00069 Variable::pushChanges() const 00070 { 00071 for (size_t i = 0; i < users.size(); ++i) { 00072 users[i]->setNeedsToRun(); 00073 } 00074 for (size_t i = 0; i < users.size(); ++i) { 00075 users[i]->run(); 00076 } 00077 } 00078 00079 #endif /* FLOWEQUATIONS_H */
1.4.7