journal.h
Engine/source/core/util/journal/journal.h
Classes:
Journaling System.
Functor base classes.
Multiple argument function functor specialization.
Public Defines
Method(Arg1, Arg2, Arg3) static Call Arg1 { \ (_Dispatching) \ return; \ (_State == PlayState) \ return; \ (_State == RecordState) { \ Id = _getFunctionId((VoidPtr)func,0); \ (,"Journal: Function must be be declared before being called"); \ _start(); \ Arg2; \ _finish(); \ } \ _Dispatching = true; \ (*func) Arg3; \ _Dispatching = false; \ return; \ }
Journal a function's return value.
Method(Arg1, Arg2, Arg3) static Call Arg1 { \ (_Dispatching) \ return; \ (_State == PlayState) \ return; \ (_State == RecordState) { \ Id = _getFunctionId((VoidPtr)obj,(VoidMethod)method); \ ( != 0,"Journal: Function must be be declared before being called"); \ _start(); \ Arg2; \ _finish(); \ } \ _Dispatching = true; \ (obj->*method) Arg3; \ _Dispatching = false; \ return; \ }
Journal a function's return value.
Method(Func, Arg1, Arg2) static typename <Func>::ValueType Result Arg1 { \ typename <Func>::ValueType value; \ (_Dispatching) \ return; \ (_State == PlayState) { \ _start(); \ (mFile,value); \ _finish(); \ return value; \ } \ _Dispatching = true; \ value = (*func) Arg2; \ _Dispatching = false; \ (_State == RecordState) { \ _start(); \ (mFile,value); \ _finish(); \ } \ return value; \ }
Journal a function's return value.
Detailed Description
Public Defines
Method(Arg1, Arg2) static inline bool Writes Arg1 { \ (_State == RecordState) { \ _start(); Arg2; _finish(); \ return true; \ } \ return false; \ }
Journal a function's return value.
Read data from the journal.
Write data into the journal.
Journal a function call.
The return value of the function is stored into the journal and retrieved during playback. During playback the function is not executed.
Store the function id and all the function's arguments into the journal. On journal playback the function is executed with the retrieved arguments. The function must have been previously declared using the declareFunction() method.
Non-deterministic data can be stored into the journal for reading during playback. The function returns true if the journal is record mode.
Read non-deterministic data stored during the recording phase. The function returns true if the journal is play mode.
Method(Arg1, Arg2) static inline bool Reads Arg1 { \ (_State == PlayState) { \ _start(); Arg2; _finish(); \ return true; \ } \ return false; \ }
Journal a function's return value.
Read data from the journal.
Write data into the journal.
Journal a function call.
The return value of the function is stored into the journal and retrieved during playback. During playback the function is not executed.
Store the function id and all the function's arguments into the journal. On journal playback the function is executed with the retrieved arguments. The function must have been previously declared using the declareFunction() method.
Non-deterministic data can be stored into the journal for reading during playback. The function returns true if the journal is record mode.
Read non-deterministic data stored during the recording phase. The function returns true if the journal is play mode.
Method(Arg1, Arg2, Arg3) static Call Arg1 { \ (_Dispatching) \ return; \ (_State == PlayState) \ return; \ (_State == RecordState) { \ Id = _getFunctionId((VoidPtr)func,0); \ (,"Journal: Function must be be declared before being called"); \ _start(); \ Arg2; \ _finish(); \ } \ _Dispatching = true; \ (*func) Arg3; \ _Dispatching = false; \ return; \ }
Journal a function's return value.
Read data from the journal.
Write data into the journal.
Journal a function call.
The return value of the function is stored into the journal and retrieved during playback. During playback the function is not executed.
Store the function id and all the function's arguments into the journal. On journal playback the function is executed with the retrieved arguments. The function must have been previously declared using the declareFunction() method.
Non-deterministic data can be stored into the journal for reading during playback. The function returns true if the journal is record mode.
Read non-deterministic data stored during the recording phase. The function returns true if the journal is play mode.
Method(Arg1, Arg2, Arg3) static Call Arg1 { \ (_Dispatching) \ return; \ (_State == PlayState) \ return; \ (_State == RecordState) { \ Id = _getFunctionId((VoidPtr)obj,(VoidMethod)method); \ ( != 0,"Journal: Function must be be declared before being called"); \ _start(); \ Arg2; \ _finish(); \ } \ _Dispatching = true; \ (obj->*method) Arg3; \ _Dispatching = false; \ return; \ }
Journal a function's return value.
Read data from the journal.
Write data into the journal.
Journal a function call.
The return value of the function is stored into the journal and retrieved during playback. During playback the function is not executed.
Store the function id and all the function's arguments into the journal. On journal playback the function is executed with the retrieved arguments. The function must have been previously declared using the declareFunction() method.
Non-deterministic data can be stored into the journal for reading during playback. The function returns true if the journal is record mode.
Read non-deterministic data stored during the recording phase. The function returns true if the journal is play mode.
Method(Func, Arg1, Arg2) static typename <Func>::ValueType Result Arg1 { \ typename <Func>::ValueType value; \ (_Dispatching) \ return; \ (_State == PlayState) { \ _start(); \ (mFile,value); \ _finish(); \ return value; \ } \ _Dispatching = true; \ value = (*func) Arg2; \ _Dispatching = false; \ (_State == RecordState) { \ _start(); \ (mFile,value); \ _finish(); \ } \ return value; \ }
Journal a function's return value.
Read data from the journal.
Write data into the journal.
Journal a function call.
The return value of the function is stored into the journal and retrieved during playback. During playback the function is not executed.
Store the function id and all the function's arguments into the journal. On journal playback the function is executed with the retrieved arguments. The function must have been previously declared using the declareFunction() method.
Non-deterministic data can be stored into the journal for reading during playback. The function returns true if the journal is record mode.
Read non-deterministic data stored during the recording phase. The function returns true if the journal is play mode.
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _UTIL_JOURNAL_JOURNAL_H_ 25#define _UTIL_JOURNAL_JOURNAL_H_ 26 27#include "platform/platform.h" 28#include "core/stream/stream.h" 29#include "util/returnType.h" 30#include "core/stream/ioHelper.h" 31#include "core/idGenerator.h" 32 33/// Journaling System. 34/// 35/// The journaling system is used to record external events and 36/// non-deterministic values from an execution run in order that the 37/// run may be re-played for debugging purposes. The journaling 38/// system is integrated into the platform library, though not all 39/// platform calls are journaled. 40/// 41/// File system calls are not journaled, so any modified files must 42/// be reset to their original state before playback. Only a single 43/// journal can be recored or played back at a time. 44/// 45/// For the journals to play back correctly, journal events cannot 46/// be triggered during the processing of another event. 47class Journal 48{ 49 Journal() {} 50 ~<a href="/coding/class/classjournal/">Journal</a>(); 51 52 static Journal smInstance; 53 54 typedef U32 Id; 55 typedef void* VoidPtr; 56 typedef void (Journal::*VoidMethod)(); 57 58 /// Functor base classes 59 struct Functor 60 { 61 Functor() {} 62 virtual ~Functor() {} 63 virtual void read(Stream *s) = 0; 64 virtual void dispatch() = 0; 65 }; 66 67 /// Multiple argument function functor specialization 68 template <class T> 69 struct FunctorDecl: public Functor { 70 typedef void(*FuncPtr)(); 71 FuncPtr ptr; 72 FunctorDecl(FuncPtr p): ptr(p) {} 73 void read(Stream *file) {} 74 void dispatch() { (*ptr)(); } 75 }; 76 77 template <class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K,class L,class M> 78 struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J,K,L,M) >: public Functor { 79 typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J,K,L,M); 80 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; M m; 81 FunctorDecl(FuncPtr p): ptr(p) {} 82 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l,m); } 83 void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j,k,l,m); } 84 }; 85 86 template <class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K,class L> 87 struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J,K,L) >: public Functor { 88 typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J,K,L); 89 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; 90 FunctorDecl(FuncPtr p): ptr(p) {} 91 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l); } 92 void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j,k,l); } 93 }; 94 95 template <class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K> 96 struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J,K) >: public Functor { 97 typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J,K); 98 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; 99 FunctorDecl(FuncPtr p): ptr(p) {} 100 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k); } 101 void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j,k); } 102 }; 103 104 template <class A,class B,class C,class D,class E,class F,class G,class H,class I,class J> 105 struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J) >: public Functor { 106 typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J); 107 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; 108 FunctorDecl(FuncPtr p): ptr(p) {} 109 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j); } 110 void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j); } 111 }; 112 113 template <class A,class B,class C,class D,class E,class F,class G,class H,class I> 114 struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I) >: public Functor { 115 typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I); 116 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; 117 FunctorDecl(FuncPtr p): ptr(p) {} 118 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i); } 119 void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i); } 120 }; 121 122 template <class A,class B,class C,class D,class E,class F,class G,class H> 123 struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H) >: public Functor { 124 typedef void(*FuncPtr)(A,B,C,D,E,F,G,H); 125 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; 126 FunctorDecl(FuncPtr p): ptr(p) {} 127 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h); } 128 void dispatch() { (*ptr)(a,b,c,d,e,f,g,h); } 129 }; 130 131 template <class A,class B,class C,class D,class E,class F,class G> 132 struct FunctorDecl< void(*)(A,B,C,D,E,F,G) >: public Functor { 133 typedef void(*FuncPtr)(A,B,C,D,E,F,G); 134 FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; 135 FunctorDecl(FuncPtr p): ptr(p) {} 136 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g); } 137 void dispatch() { (*ptr)(a,b,c,d,e,f,g); } 138 }; 139 140 template <class A,class B,class C,class D,class E,class F> 141 struct FunctorDecl< void(*)(A,B,C,D,E,F) >: public Functor { 142 typedef void(*FuncPtr)(A,B,C,D,E,F); 143 FuncPtr ptr; A a; B b; C c; D d; E e; F f; 144 FunctorDecl(FuncPtr p): ptr(p) {} 145 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f); } 146 void dispatch() { (*ptr)(a,b,c,d,e,f); } 147 }; 148 149 template <class A,class B,class C,class D,class E> 150 struct FunctorDecl< void(*)(A,B,C,D,E) >: public Functor { 151 typedef void(*FuncPtr)(A,B,C,D,E); 152 FuncPtr ptr; A a; B b; C c; D d; E e; 153 FunctorDecl(FuncPtr p): ptr(p) {} 154 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e); } 155 void dispatch() { (*ptr)(a,b,c,d,e); } 156 }; 157 158 template <class A,class B,class C,class D> 159 struct FunctorDecl< void(*)(A,B,C,D) >: public Functor { 160 typedef void(*FuncPtr)(A,B,C,D); 161 FuncPtr ptr; A a; B b; C c; D d; 162 FunctorDecl(FuncPtr p): ptr(p) {} 163 void read(Stream *file) { IOHelper::reads(file,a,b,c,d); } 164 void dispatch() { (*ptr)(a,b,c,d); } 165 }; 166 167 template <class A,class B,class C> 168 struct FunctorDecl< void(*)(A,B,C) >: public Functor { 169 typedef void(*FuncPtr)(A,B,C); 170 FuncPtr ptr; A a; B b; C c; 171 FunctorDecl(FuncPtr p): ptr(p) {} 172 void read(Stream *file) { IOHelper::reads(file,a,b,c); } 173 void dispatch() { (*ptr)(a,b,c); } 174 }; 175 176 template <class A,class B> 177 struct FunctorDecl< void(*)(A,B) >: public Functor { 178 typedef void(*FuncPtr)(A,B); 179 FuncPtr ptr; A a; B b; 180 FunctorDecl(FuncPtr p): ptr(p) {} 181 void read(Stream *file) { IOHelper::reads(file,a,b); } 182 void dispatch() { (*ptr)(a,b); } 183 }; 184 185 template <class A> 186 struct FunctorDecl< void(*)(A) >: public Functor { 187 typedef void(*FuncPtr)(A); 188 FuncPtr ptr; A a; 189 FunctorDecl(FuncPtr p): ptr(p) {} 190 void read(Stream *file) { IOHelper::reads(file,a); } 191 void dispatch() { (*ptr)(a); } 192 }; 193 194 // Multiple argument object member function functor specialization 195 template <class T,class U> 196 struct MethodDecl: public Functor { 197 typedef T ObjPtr; 198 typedef U MethodPtr; 199 ObjPtr obj; MethodPtr method; 200 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 201 void read(Stream *file) {} 202 void dispatch() { (obj->*method)(); } 203 }; 204 205 template <class T,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K,class L,class M> 206 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G,H,I,J,K,L,M) >: public Functor { 207 typedef T* ObjPtr; 208 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J,K,L,M); 209 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; M m; 210 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 211 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l,m); } 212 void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j,k,l,m); } 213 }; 214 215 template <class T,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K,class L> 216 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G,H,I,J,K,L) >: public Functor { 217 typedef T* ObjPtr; 218 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J,K,L); 219 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; 220 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 221 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l); } 222 void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j,k,l); } 223 }; 224 225 template <class T,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K> 226 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G,H,I,J,K) >: public Functor { 227 typedef T* ObjPtr; 228 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J,K); 229 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; 230 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 231 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k); } 232 void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j,k); } 233 }; 234 235 template <class T,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J> 236 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G,H,I,J) >: public Functor { 237 typedef T* ObjPtr; 238 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J); 239 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; 240 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 241 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j); } 242 void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j); } 243 }; 244 245 template <class T,class A,class B,class C,class D,class E,class F,class G,class H,class I> 246 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G,H,I) >: public Functor { 247 typedef T* ObjPtr; 248 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I); 249 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; 250 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 251 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i); } 252 void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i); } 253 }; 254 255 template <class T,class A,class B,class C,class D,class E,class F,class G,class H> 256 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G,H) >: public Functor { 257 typedef T* ObjPtr; 258 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H); 259 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; 260 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 261 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h); } 262 void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h); } 263 }; 264 265 template <class T,class A,class B,class C,class D,class E,class F,class G> 266 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F,G) >: public Functor { 267 typedef T* ObjPtr; 268 typedef void(T::*MethodPtr)(A,B,C,D,E,F,G); 269 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; 270 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 271 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g); } 272 void dispatch() { (obj->*method)(a,b,c,d,e,f,g); } 273 }; 274 275 template <class T,class A,class B,class C,class D,class E,class F> 276 struct MethodDecl<T*, void(T::*)(A,B,C,D,E,F) >: public Functor { 277 typedef T* ObjPtr; 278 typedef void(T::*MethodPtr)(A,B,C,D,E,F); 279 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; 280 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 281 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f); } 282 void dispatch() { (obj->*method)(a,b,c,d,e,f); } 283 }; 284 285 template <class T,class A,class B,class C,class D,class E> 286 struct MethodDecl<T*, void(T::*)(A,B,C,D,E) >: public Functor { 287 typedef T* ObjPtr; 288 typedef void(T::*MethodPtr)(A,B,C,D,E); 289 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; 290 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 291 void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e); } 292 void dispatch() { (obj->*method)(a,b,c,d,e); } 293 }; 294 295 template <class T,class A,class B,class C,class D> 296 struct MethodDecl<T*, void(T::*)(A,B,C,D) >: public Functor { 297 typedef T* ObjPtr; 298 typedef void(T::*MethodPtr)(A,B,C,D); 299 ObjPtr obj; MethodPtr method; A a; B b; C c; D d; 300 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 301 void read(Stream *file) { IOHelper::reads(file,a,b,c,d); } 302 void dispatch() { (obj->*method)(a,b,c,d); } 303 }; 304 305 template <class T,class A,class B,class C> 306 struct MethodDecl<T*, void(T::*)(A,B,C) >: public Functor { 307 typedef T* ObjPtr; 308 typedef void(T::*MethodPtr)(A,B,C); 309 ObjPtr obj; MethodPtr method; A a; B b; C c; 310 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 311 void read(Stream *file) { IOHelper::reads(file,a,b,c); } 312 void dispatch() { (obj->*method)(a,b,c); } 313 }; 314 315 template <class T,class A,class B> 316 struct MethodDecl<T*, void(T::*)(A,B) >: public Functor { 317 typedef T* ObjPtr; 318 typedef void(T::*MethodPtr)(A,B); 319 ObjPtr obj; MethodPtr method; A a; B b; 320 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 321 void read(Stream *file) { IOHelper::reads(file,a,b); } 322 void dispatch() { (obj->*method)(a,b); } 323 }; 324 325 template <class T,class A> 326 struct MethodDecl<T*, void(T::*)(A) >: public Functor { 327 typedef T* ObjPtr; 328 typedef void(T::*MethodPtr)(A); 329 ObjPtr obj; MethodPtr method; A a; 330 MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} 331 void read(Stream *file) { IOHelper::reads(file,a); } 332 void dispatch() { (obj->*method)(a); } 333 }; 334 335 // Function declarations 336 struct FuncDecl { 337 FuncDecl* next; 338 Id id; 339 virtual ~FuncDecl() {} 340 virtual bool match(VoidPtr,VoidMethod) const = 0; 341 virtual Functor* create() const = 0; 342 }; 343 344 template<typename T> 345 struct FuncRep: public FuncDecl { 346 typename T::FuncPtr function; 347 virtual bool match(VoidPtr ptr,VoidMethod) const { 348 return function == (typename T::FuncPtr)ptr; 349 } 350 T* create() const { return new T(function); }; 351 }; 352 353 template<typename T> 354 struct MethodRep: public FuncDecl { 355 typename T::ObjPtr obj; 356 typename T::MethodPtr method; 357 virtual bool match(VoidPtr ptr,VoidMethod func) const { 358 return obj == (typename T::ObjPtr)ptr && method == (typename T::MethodPtr)func; 359 } 360 T* create() const { return new T(obj,method); }; 361 }; 362 363 static FuncDecl* _FunctionList; 364 365 static inline IdGenerator &idPool() 366 { 367 static IdGenerator _IdPool(1, 65535); 368 return _IdPool; 369 } 370 371 static U32 _Count; 372 static Stream *mFile; 373 static enum Mode { 374 StopState, PlayState, RecordState, DisabledState 375 } _State; 376 static bool _Dispatching; 377 378 static Functor* _create(Id id); 379 static void _start(); 380 static void _finish(); 381 static Id _getFunctionId(VoidPtr ptr,VoidMethod method); 382 static void _removeFunctionId(VoidPtr ptr,VoidMethod method); 383 384public: 385 static void Record(const char * file); 386 static void Play(const char * file); 387 static bool PlayNext(); 388 static void Stop(); 389 static void Disable(); 390 391 /// Returns true if in recording mode. 392 static inline bool IsRecording() { 393 return _State == RecordState; 394 } 395 396 /// Returns true if in play mode. 397 static inline bool IsPlaying() { 398 return _State == PlayState; 399 } 400 401 /// Returns true if a function is being dispatched 402 static inline bool IsDispatching() { 403 return _Dispatching; 404 } 405 406 template<typename T> 407 static void Read(T *v) 408 { 409 AssertFatal(IsPlaying(), "Journal::Read - not playing right now."); 410 bool r = mFile->read(v); 411 AssertFatal(r, "Journal::Read - failed to read!"); 412 } 413 414 static bool Read(U32 size, void *buffer) 415 { 416 AssertFatal(IsPlaying(), "Journal::Read - not playing right now."); 417 bool r = mFile->read(size, buffer); 418 AssertFatal(r, "Journal::Read - failed to read!"); 419 return r; 420 } 421 422 static void ReadString(char str[256]) 423 { 424 AssertFatal(IsPlaying(), "Journal::ReadString - not playing right now."); 425 mFile->readString(str); 426 } 427 428 template<typename T> 429 static void Write(const T &v) 430 { 431 AssertFatal(IsRecording(), "Journal::Write - not recording right now."); 432 bool r = mFile->write(v); 433 AssertFatal(r, "Journal::Write - failed to write!"); 434 } 435 436 static bool Write(U32 size, void *buffer) 437 { 438 AssertFatal(IsRecording(), "Journal::Write - not recording right now."); 439 bool r = mFile->write(size, buffer); 440 AssertFatal(r, "Journal::Write - failed to write!"); 441 return r; 442 } 443 444 static void WriteString(const char str[256]) 445 { 446 AssertFatal(IsRecording(), "Journal::WriteString - not recording right now."); 447 mFile->writeString(str); 448 } 449 450 /// Register a function with the journalling system. 451 template<typename T> 452 static void DeclareFunction(T func) { 453 if (!_getFunctionId((VoidPtr)func,0)) { 454 FuncRep<FunctorDecl<T> >* decl = new FuncRep<FunctorDecl<T> >; 455 decl->function = func; 456 decl->id = idPool().alloc(); 457 decl->next = _FunctionList; 458 _FunctionList = decl; 459 } 460 } 461 462 template<typename T, typename U> 463 static void DeclareFunction(T obj, U method) 464 { 465 if (!_getFunctionId((VoidPtr)obj,(VoidMethod)method)) { 466 MethodRep<MethodDecl<T,U> >* decl = new MethodRep<MethodDecl<T,U> >; 467 decl->obj = obj; 468 decl->method = method; 469 decl->id = idPool().alloc(); 470 decl->next = _FunctionList; 471 _FunctionList = decl; 472 } 473 } 474 475 template<typename T, typename U> 476 static void RemoveFunction(T obj, U method) 477 { 478 _removeFunctionId((VoidPtr)obj,(VoidMethod)method); 479 } 480 481 /// Journal a function's return value. The return value of the 482 /// function is stored into the journal and retrieved during 483 /// playback. During playback the function is not executed. 484 #define Method(Func,Arg1,Arg2) \ 485 static typename ReturnType<Func>::ValueType Result Arg1 { \ 486 typename ReturnType<Func>::ValueType value; \ 487 if (_Dispatching) \ 488 return; \ 489 if (_State == PlayState) { \ 490 _start(); \ 491 IOHelper::reads(mFile,value); \ 492 _finish(); \ 493 return value; \ 494 } \ 495 _Dispatching = true; \ 496 value = (*func) Arg2; \ 497 _Dispatching = false; \ 498 if (_State == RecordState) { \ 499 _start(); \ 500 IOHelper::writes(mFile,value); \ 501 _finish(); \ 502 } \ 503 return value; \ 504 } 505 506 template<class Func,class A,class B,class C,class D,class E,class F, class G, class H, class I, class J, class K, class L, class M> 507 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j, K k, L l, M m),(a,b,c,d,e,f,g,h,i,j,k,l,m)) 508 template<class Func,class A,class B,class C,class D,class E,class F, class G, class H, class I, class J, class K, class L> 509 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j, K k, L l),(a,b,c,d,e,f,g,h,i,j,k,l)) 510 template<class Func,class A,class B,class C,class D,class E,class F, class G, class H, class I, class J, class K> 511 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j, K k),(a,b,c,d,e,f,g,h,i,j,k)) 512 template<class Func,class A,class B,class C,class D,class E,class F, class G, class H, class I, class J> 513 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j),(a,b,c,d,e,f,g,h,i,j)) 514 template<class Func,class A,class B,class C,class D,class E,class F, class G, class H, class I> 515 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i),(a,b,c,d,e,f,g,h,i)) 516 template<class Func,class A,class B,class C,class D,class E,class F, class G, class H> 517 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h),(a,b,c,d,e,f,g,h)) 518 template<class Func,class A,class B,class C,class D,class E,class F, class G> 519 Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g),(a,b,c,d,e,f,g)) 520 template<class Func,class A,class B,class C,class D,class E,class F> 521 Method(Func,(Func func,A a,B b,C c,D d,E e,F f),(a,b,c,d,e,f)) 522 template<class Func,class A,class B,class C,class D,class E> 523 Method(Func,(Func func,A a,B b,C c,D d,E e),(a,b,c,d,e)) 524 template<class Func,class A,class B,class C,class D> 525 Method(Func,(Func func,A a,B b,C c,D d),(a,b,c,d)) 526 template<class Func,class A,class B,class C> 527 Method(Func,(Func func,A a,B b,C c),(a,b,c)) 528 template<class Func,class A,class B> 529 Method(Func,(Func func,A a,B b),(a,b)) 530 template<class Func,class A> 531 Method(Func,(Func func,A a),(a)) 532 template<class Func> 533 Method(Func,(Func func),()) 534 #undef Method 535 536 /// Journal a function call. Store the function id and all the 537 /// function's arguments into the journal. On journal playback the 538 /// function is executed with the retrieved arguments. The function 539 /// must have been previously declared using the declareFunction() 540 /// method. 541 #define Method(Arg1,Arg2,Arg3) \ 542 static void Call Arg1 { \ 543 if (_Dispatching) \ 544 return; \ 545 if (_State == PlayState) \ 546 return; \ 547 if (_State == RecordState) { \ 548 Id id = _getFunctionId((VoidPtr)func,0); \ 549 AssertFatal(id,"Journal: Function must be be declared before being called"); \ 550 _start(); \ 551 IOHelper::writes Arg2; \ 552 _finish(); \ 553 } \ 554 _Dispatching = true; \ 555 (*func) Arg3; \ 556 _Dispatching = false; \ 557 return; \ 558 } 559 560 template<class Func,class A,class B,class C,class D,class E, class F, class G, class H, class I, class J, class K, class L, class M> 561 Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l,M m),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l,m),(a,b,c,d,e,f,g,h,i,j,k,l,m)) 562 template<class Func,class A,class B,class C,class D,class E, class F, class G, class H, class I, class J, class K, class L> 563 Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l),(a,b,c,d,e,f,g,h,i,j,k,l)) 564 template<class Func,class A,class B,class C,class D,class E, class F, class G, class H, class I, class J, class K> 565 Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k),(mFile,id,a,b,c,d,e,f,g,h,i,j,k),(a,b,c,d,e,f,g,h,i,j,k)) 566 template<class Func,class A,class B,class C,class D,class E, class F, class G, class H, class I, class J> 567 Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j),(mFile,id,a,b,c,d,e,f,g,h,i,j),(a,b,c,d,e,f,g,h,i,j)) 568 template<class Func,class A,class B,class C,class D,class E, class F, class G, class H, class I> 569 Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i),(mFile,id,a,b,c,d,e,f,g,h,i),(a,b,c,d,e,f,g,h,i)) 570 template<class Func,class A,class B,class C,class D,class E, class F, class G, class H> 571 Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h),(mFile,id,a,b,c,d,e,f,g,h),(a,b,c,d,e,f,g,h)) 572 template<class Func,class A,class B,class C,class D,class E, class F, class G> 573 Method((Func func,A a,B b,C c,D d,E e,F f,G g),(mFile,id,a,b,c,d,e,f,g),(a,b,c,d,e,f,g)) 574 template<class Func,class A,class B,class C,class D,class E, class F> 575 Method((Func func,A a,B b,C c,D d,E e,F f),(mFile,id,a,b,c,d,e,f),(a,b,c,d,e,f)) 576 template<class Func,class A,class B,class C,class D,class E> 577 Method((Func func,A a,B b,C c,D d,E e),(mFile,id,a,b,c,d,e),(a,b,c,d,e)) 578 template<class Func,class A,class B,class C,class D> 579 Method((Func func,A a,B b,C c,D d),(mFile,id,a,b,c,d),(a,b,c,d)) 580 template<class Func,class A,class B,class C> 581 Method((Func func,A a,B b,C c),(mFile,id,a,b,c),(a,b,c)) 582 template<class Func,class A,class B> 583 Method((Func func,A a,B b),(mFile,id,a,b),(a,b)) 584 template<class Func,class A> 585 Method((Func func,A a),(mFile,id,a),(a)) 586 template<class Func> 587 Method((Func func),(mFile,id),()) 588 #undef Method 589 590 #define Method(Arg1,Arg2,Arg3) \ 591 static void Call Arg1 { \ 592 if (_Dispatching) \ 593 return; \ 594 if (_State == PlayState) \ 595 return; \ 596 if (_State == RecordState) { \ 597 Id id = _getFunctionId((VoidPtr)obj,(VoidMethod)method); \ 598 AssertFatal(id != 0,"Journal: Function must be be declared before being called"); \ 599 _start(); \ 600 IOHelper::writes Arg2; \ 601 _finish(); \ 602 } \ 603 _Dispatching = true; \ 604 (obj->*method) Arg3; \ 605 _Dispatching = false; \ 606 return; \ 607 } 608 609 610 template<class Obj,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K,class L,class M> 611 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J,K,L,M),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l,M m),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l,m),(a,b,c,d,e,f,g,h,i,j,k,l,m)) 612 template<class Obj,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K,class L> 613 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J,K,L),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l),(a,b,c,d,e,f,g,h,i,j,k,l)) 614 template<class Obj,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J,class K> 615 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J,K),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k),(mFile,id,a,b,c,d,e,f,g,h,i,j,k),(a,b,c,d,e,f,g,h,i,j,k)) 616 template<class Obj,class A,class B,class C,class D,class E,class F,class G,class H,class I,class J> 617 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j),(mFile,id,a,b,c,d,e,f,g,h,i,j),(a,b,c,d,e,f,g,h,i,j)) 618 template<class Obj,class A,class B,class C,class D,class E,class F,class G,class H,class I> 619 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I),A a,B b,C c,D d,E e,F f,G g,H h,I i),(mFile,id,a,b,c,d,e,f,g,h,i),(a,b,c,d,e,f,g,h,i)) 620 template<class Obj,class A,class B,class C,class D,class E,class F,class G,class H> 621 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H),A a,B b,C c,D d,E e,F f,G g,H h),(mFile,id,a,b,c,d,e,f,g,h),(a,b,c,d,e,f,g,h)) 622 template<class Obj,class A,class B,class C,class D,class E,class F,class G> 623 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G),A a,B b,C c,D d,E e,F f,G g),(mFile,id,a,b,c,d,e,f,g),(a,b,c,d,e,f,g)) 624 template<class Obj,class A,class B,class C,class D,class E,class F> 625 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F),A a,B b,C c,D d,E e,F f),(mFile,id,a,b,c,d,e,f),(a,b,c,d,e,f)) 626 template<class Obj,class A,class B,class C,class D,class E> 627 Method((Obj* obj,void (Obj::*method)(A,B,C,D,E),A a,B b,C c,D d,E e),(mFile,id,a,b,c,d,e),(a,b,c,d,e)) 628 template<class Obj,class A,class B,class C,class D> 629 Method((Obj* obj,void (Obj::*method)(A,B,C,D),A a,B b,C c,D d),(mFile,id,a,b,c,d),(a,b,c,d)) 630 template<class Obj,class A,class B,class C> 631 Method((Obj* obj,void (Obj::*method)(A,B,C),A a,B b,C c),(mFile,id,a,b,c),(a,b,c)) 632 template<class Obj,class A,class B> 633 Method((Obj* obj,void (Obj::*method)(A,B),A a,B b),(mFile,id,a,b),(a,b)) 634 template<class Obj,class A> 635 Method((Obj* obj,void (Obj::*method)(A),A a),(mFile,id,a),(a)) 636 template<class Obj> 637 Method((Obj* obj,void (Obj::*method)()),(mFile,id),()) 638 639 #undef Method 640 641 /// Write data into the journal. Non-deterministic data can be stored 642 /// into the journal for reading during playback. The function 643 /// returns true if the journal is record mode. 644 #define Method(Arg1,Arg2) \ 645 static inline bool Writes Arg1 { \ 646 if (_State == RecordState) { \ 647 _start(); IOHelper::writes Arg2; _finish(); \ 648 return true; \ 649 } \ 650 return false; \ 651 } 652 653 template<class A,class B,class C,class D,class E, class F, class G, class H,class I,class J,class K,class L,class M> 654 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j,K& k,L& l,M& m),(mFile,a,b,c,d,e,f,g,h,i,j,k,l,m)); 655 template<class A,class B,class C,class D,class E, class F, class G, class H,class I,class J,class K,class L> 656 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j,K& k,L& l),(mFile,a,b,c,d,e,f,g,h,i,j,k,l)); 657 template<class A,class B,class C,class D,class E, class F, class G, class H,class I,class J,class K> 658 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j,K& k),(mFile,a,b,c,d,e,f,g,h,i,j,k)); 659 template<class A,class B,class C,class D,class E, class F, class G, class H,class I,class J> 660 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j),(mFile,a,b,c,d,e,f,g,h,i,j)); 661 template<class A,class B,class C,class D,class E, class F, class G, class H,class I> 662 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i),(mFile,a,b,c,d,e,f,g,h,i)); 663 template<class A,class B,class C,class D,class E, class F, class G, class H> 664 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h),(mFile,a,b,c,d,e,f,g,h)); 665 template<class A,class B,class C,class D,class E, class F, class G> 666 Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g),(mFile,a,b,c,d,e,f,g)); 667 template<class A,class B,class C,class D,class E, class F> 668 Method((A& a,B& b,C& c,D& d,E& e, F& f),(mFile,a,b,c,d,e,f)); 669 template<class A,class B,class C,class D,class E> 670 Method((A& a,B& b,C& c,D& d,E& e),(mFile,a,b,c,d,e)); 671 template<class A,class B,class C,class D> 672 Method((A& a,B& b,C& c,D& d),(mFile,a,b,c,d)); 673 template<class A,class B,class C> 674 Method((A& a,B& b,C& c),(mFile,a,b,c)); 675 template<class A,class B> 676 Method((A& a,B& b),(mFile,a,b)); 677 template<class A> 678 Method((A& a),(mFile,a)); 679 #undef Method 680 681 /// Read data from the journal. Read non-deterministic data stored 682 /// during the recording phase. The function returns true if the 683 /// journal is play mode. 684 #define Method(Arg1,Arg2) \ 685 static inline bool Reads Arg1 { \ 686 if (_State == PlayState) { \ 687 _start(); IOHelper::reads Arg2; _finish(); \ 688 return true; \ 689 } \ 690 return false; \ 691 } 692 693 template<class A,class B,class C,class D,class E, class F, class G, class H, class I, class J, class K,class L,class M> 694 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j, K& k, L& l, M& m),(mFile,a,b,c,d,e,f,g,h,i,j,k,l,m)); 695 template<class A,class B,class C,class D,class E, class F, class G, class H, class I, class J, class K,class L> 696 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j, K& k, L& l),(mFile,a,b,c,d,e,f,g,h,i,j,k,l)); 697 template<class A,class B,class C,class D,class E, class F, class G, class H, class I, class J, class K> 698 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j, K& k),(mFile,a,b,c,d,e,f,g,h,i,j,k)); 699 template<class A,class B,class C,class D,class E, class F, class G, class H, class I, class J> 700 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j),(mFile,a,b,c,d,e,f,g,h,i,j)); 701 template<class A,class B,class C,class D,class E, class F, class G, class H, class I> 702 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i),(mFile,a,b,c,d,e,f,g,h,i)); 703 template<class A,class B,class C,class D,class E, class F, class G, class H> 704 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h),(mFile,a,b,c,d,e,f,g,h)); 705 template<class A,class B,class C,class D,class E, class F, class G> 706 Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g),(mFile,a,b,c,d,e,f,g)); 707 template<class A,class B,class C,class D,class E, class F> 708 Method((A& a,B& b,C& c,D& d,E& e,F& f),(mFile,a,b,c,d,e,f)); 709 template<class A,class B,class C,class D,class E> 710 Method((A& a,B& b,C& c,D& d,E& e),(mFile,a,b,c,d,e)); 711 template<class A,class B,class C,class D> 712 Method((A& a,B& b,C& c,D& d),(mFile,a,b,c,d)); 713 template<class A,class B,class C> 714 Method((A& a,B& b,C& c),(mFile,a,b,c)); 715 template<class A,class B> 716 Method((A& a,B& b),(mFile,a,b)); 717 template<class A> 718 Method((A& a),(mFile,a)); 719 720 #undef Method 721}; 722 723#endif 724
