00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Side Effects Software Inc. 00008 * 477 Richmond Street West, Suite 1001 00009 * Toronto, Ontario 00010 * Canada M5V 3E7 00011 * 416-504-9876 00012 */ 00013 00014 #ifndef __SIM_Cache_h__ 00015 #define __SIM_Cache_h__ 00016 00017 #include "SIM_API.h" 00018 #include <UT/UT_LinkList.h> 00019 #include "SIM_Utils.h" 00020 #include "SIM_Object.h" 00021 #include "SIM_ObjectArray.h" 00022 #include "SIM_CacheOptions.h" 00023 00024 class SIM_Engine; 00025 class SIM_CacheEntry; 00026 class SIM_SimulationState; 00027 00028 /// This class is the cache for a SIM_Engine. 00029 /// It holds all the actual objects for the simulation for the entire 00030 /// cached time range. 00031 class SIM_API SIM_Cache 00032 { 00033 public: 00034 /// Constructor intializes this class with no object data. 00035 /// A single cache entry is created to hold any new objects. 00036 SIM_Cache(); 00037 /// Destructor destroys all objects and temp files. 00038 ~SIM_Cache(); 00039 00040 /// Initialize this object with a SIM_Engine pointer. This must be 00041 /// done as soon as the SIM_Cache is created. 00042 void setEngine(SIM_Engine *engine); 00043 /// Returns a reference to our caching option data. 00044 const SIM_CacheOptions &getCacheOptions() const; 00045 /// Sets the cache options. 00046 void setCacheOptions(const SIM_CacheOptions &src); 00047 00048 /// Caches the current object data and advances by one time step. 00049 /// Basically this consists of creating a copy of all objects in the 00050 /// simulation and setting the new current time. If the cache size 00051 /// is exceeded, a cache entry will be deleted. A cache entry may 00052 /// also get pushed to disk. If caching is disabled, this function 00053 /// does nothing except advance the current time. 00054 void cacheAndAdvance(); 00055 /// Tells the cache to move to a new current time. 00056 /// Whatever cache entry is the best match for the specfied time will 00057 /// be made the current cache entry. If the new time is earlier than any 00058 /// cache entry, then the earliest cache entry is used. If the new time 00059 /// is later than the latest cache entry, the last entry is used. Note 00060 /// that this means the cache's current time won't necessarily be set 00061 /// to the requested value. It is up to the SIM_Engine to perform 00062 /// simulation steps to get to the actual desired time. 00063 void setCurrentTime(const SIM_Time &time); 00064 /// Deletes all cache entries after the specified time. The cache 00065 /// entry for the specified time itself is also deleted. The cache 00066 /// is moved to the entry just prior to the earliest deleted entry. 00067 /// If there is insufficient cache to fulfil the request, then nothing 00068 /// is changed and the function returns false. Otherwise it returns 00069 /// true. 00070 bool deleteAfterTime(const SIM_Time &time); 00071 /// Clears all cache entries. A single empty cache entry is then 00072 /// created to act as the current entry to shich new objects may be 00073 /// added. 00074 void clear(); 00075 00076 /// Returns the time of the current cache entry. This function is 00077 /// called by the SIM_Engine::getSimulationTime() function. 00078 const SIM_Time &getCurrentTime() const; 00079 /// Returns the time of the earliest cache entry. This function is 00080 /// called by the SIM_Engine::getEarliestCacheTime() function. 00081 const SIM_Time &getEarliestTime() const; 00082 /// Returns the objects that belong to the current cache entry. 00083 /// This function is called by the SIM_Engine getSimulationObject() 00084 /// and related functions. 00085 SIM_SimulationState &getCurrentSimulationObjects() const; 00086 00087 /// Returns the specified object at an earlier time step. If the object 00088 /// at the exact specified time cannot be found, we create a new object 00089 /// by interpolating between the previous and next available states of 00090 /// the object. 00091 const SIM_Object *getObjectAtTime(const SIM_Object &object, 00092 const SIM_Time &time, 00093 bool allowinterpolation); 00094 /// Returns a non-const object from the specified earlier time. The 00095 /// returned value is always a pointer to the passed in object, or a 00096 /// substep object. If a time in some earlier timestep is specified, 00097 /// the earlier object is copied as a substep object of the current 00098 /// time. Otheriwse this function could be used to modify the past. 00099 SIM_Object *getAffectorAtTime(SIM_Object &object, 00100 const SIM_Time &time, 00101 bool allowinterpolation); 00102 /// Returns a substep version of the specified object. The substep 00103 /// object is always created within the current simulation state 00104 /// regardless of the time value. The reason the SIM_Cache is used 00105 /// as an intermediary here is so that if we already have an 00106 /// interpolated version of the object at the requested time, we 00107 /// can convert the interpolated object into a substep (which is 00108 /// really different only in the sense of whether the SIM_Cache or 00109 /// the SIM_SimulationState owns it). 00110 SIM_Object *createSubStepObject(const SIM_Object &object, 00111 const SIM_Time &time); 00112 /// Deletes any objects from the myInterpolatedObjects array that 00113 /// match the provided object id. This function is called by the 00114 /// engine just prior to solving the object. The idea is that the 00115 /// object may have been used to create an interpolated object prior 00116 /// to its solve for a given timestep. After its solve, all the 00117 /// interpolation is incorrect, so leaving the interpolated objects 00118 /// around is potentially misleading and harmful. 00119 void clearInterpolatedObjects( 00120 const SIM_ObjectArray &objects); 00121 /// This performs the cleanup required after performing a simulation step. 00122 /// All temporary interpolated objects are deleted, and any excess cache 00123 /// entries in memory are flushed to disk. 00124 void postSimulationStep(); 00125 00126 private: 00127 /// Loads a cache entry from disk (if it's not already in memory). 00128 void loadFromDisk(SIM_CacheEntry *entry); 00129 /// Moves some cache entries from memory to disk if we have too many 00130 /// in memory. 00131 void ensureCacheCompliesWithOptions(); 00132 /// Interpolated objects use for display are stored outside of any 00133 /// cache entry. This function clears out those interpolated objects. 00134 void clearInterpolatedObjects(bool clearsubsteps); 00135 /// Utility function used by getObjectAtTime() and getAffectorAtTime(). 00136 /// It finds the closest existing objects to the requested object. 00137 void getBestObjects(const SIM_Object *object, 00138 const SIM_Time &time, 00139 bool allowinterpolation, 00140 const SIM_Object *&matchobject, 00141 SIM_Object *&nonconstmatchobject, 00142 const SIM_Object *&bestbeforeobject, 00143 SIM_Time &bestbeforetime, 00144 const SIM_Object *&bestafterobject, 00145 SIM_Time &bestaftertime); 00146 /// Get the initial entry, which is the simulation state that shows 00147 /// up for all times less then zero, and which is copied to be the 00148 /// first timestep state when the cache is cleared. 00149 SIM_CacheEntry *getInitialEntry(); 00150 /// Clears the initial entry. 00151 void clearInitialEntry(); 00152 /// Get our current cache entry. 00153 SIM_CacheEntry *getCurrentEntry() const; 00154 /// Set our current cache entry. 00155 void setCurrentEntry(SIM_CacheEntry *newentry); 00156 00157 SIM_Engine *myEngine; 00158 SIM_CacheOptions myCacheOptions; 00159 UT_LinkList myCacheEntries; 00160 SIM_CacheEntry *myCurrentEntry; 00161 SIM_CacheEntry *myInitialEntry; 00162 SIM_ObjectAtTimeMatrix myInterpolatedObjects; 00163 }; 00164 00165 #endif 00166
1.5.9