journal.cpp
Engine/source/core/util/journal/journal.cpp
Detailed Description
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#include "platform/platform.h" 25#include "core/util/journal/journal.h" 26 27#include "core/stream/fileStream.h" 28#include "core/util/safeDelete.h" 29#include "console/console.h" 30#include <stdlib.h> 31 32//----------------------------------------------------------------------------- 33 34Journal::FuncDecl* Journal::_FunctionList; 35Stream *Journal::mFile; 36Journal::Mode Journal::_State = Journal::StopState; 37U32 Journal::_Count; 38bool Journal::_Dispatching = false; 39 40Journal Journal::smInstance; 41 42//----------------------------------------------------------------------------- 43Journal::~Journal() 44{ 45 if( mFile ) 46 Stop(); 47} 48 49//----------------------------------------------------------------------------- 50 51Journal::Functor* Journal::_create(Id id) 52{ 53 for (FuncDecl* ptr = _FunctionList; ptr; ptr = ptr->next) 54 if (ptr->id == id) 55 return ptr->create(); 56 return 0; 57} 58 59Journal::Id Journal::_getFunctionId(VoidPtr ptr,VoidMethod method) 60{ 61 for (FuncDecl* itr = _FunctionList; itr; itr = itr->next) 62 if (itr->match(ptr,method)) 63 return itr->id; 64 return 0; 65} 66 67void Journal::_removeFunctionId(VoidPtr ptr,VoidMethod method) 68{ 69 FuncDecl ** itr = &_FunctionList; 70 71 do 72 { 73 if((*itr)->match(ptr, method)) 74 { 75 // Unlink and break. 76 FuncDecl* decl = *itr; 77 idPool().free( decl->id ); 78 *itr = (*itr)->next; 79 delete decl; 80 return; 81 } 82 83 // Advance to next... 84 itr = &((*itr)->next); 85 } 86 while(*itr); 87} 88 89void Journal::_start() 90{ 91} 92 93void Journal::_finish() 94{ 95 if (_State == PlayState) 96 --_Count; 97 else { 98 U32 pos = mFile->getPosition(); 99 mFile->setPosition(0); 100 mFile->write(++_Count); 101 mFile->setPosition(pos); 102 } 103} 104 105void Journal::Record(const char * file) 106{ 107 if (_State == DisabledState) 108 { 109 Con::errorf("//---------------------------------------------//"); 110 Con::errorf("Journal::Record() - Cannot record a journal after GuiCanvas or NetConnection creation!"); 111 Con::errorf("To record before canvas/netConnection creation, run %s with the following arguments: -jSave %s", 112 Platform::getExecutableName(), file); 113 Con::errorf("//---------------------------------------------//"); 114 return; 115 } 116 117 if (_State == StopState) 118 { 119 _Count = 0; 120 mFile = new FileStream(); 121 122 if( ((FileStream*)mFile)->open(file, Torque::FS::File::Write) ) 123 { 124 mFile->write(_Count); 125 _State = RecordState; 126 } 127 else 128 { 129 AssertWarn(false,"Journal: Could not create journal file"); 130 Con::errorf("Journal: Could not create journal file '%s'", file); 131 } 132 } 133} 134 135void Journal::Play(const char * file) 136{ 137 if (_State == DisabledState) 138 { 139 Con::errorf("//---------------------------------------------//"); 140 Con::errorf("Journal::Play() - Cannot playback a journal after GuiCanvas or NetConnection creation!"); 141 Con::errorf("To playback before canvas/netConnection creation, run %s with the following arguments: -jPlay %s", 142 Platform::getExecutableName(), file); 143 Con::errorf("//---------------------------------------------//"); 144 return; 145 } 146 147 if (_State == StopState) 148 { 149 SAFE_DELETE(mFile); 150 mFile = new FileStream(); 151 if( ((FileStream*)mFile)->open(file, Torque::FS::File::Read) ) 152 { 153 mFile->read(&_Count); 154 _State = PlayState; 155 } 156 else 157 { 158 AssertWarn(false,"Journal: Could not open journal file"); 159 Con::errorf("Journal: Could not open journal file '%s'", file); 160 } 161 } 162} 163 164void Journal::Stop() 165{ 166 AssertFatal(mFile, "Journal::Stop - no file stream open!"); 167 168 SAFE_DELETE( mFile ); 169 _State = StopState; 170} 171 172bool Journal::PlayNext() 173{ 174 if (_State == PlayState) { 175 _start(); 176 Id id; 177 178 mFile->read(&id); 179 180 Functor* jrn = _create(id); 181 AssertFatal(jrn,"Journal: Undefined function found in journal"); 182 jrn->read(mFile); 183 _finish(); 184 185 _Dispatching = true; 186 jrn->dispatch(); 187 _Dispatching = false; 188 189 delete jrn; 190 if (_Count) 191 return true; 192 Stop(); 193 194 //debugBreak(); 195 } 196 return false; 197} 198 199void Journal::Disable() 200{ 201 if (_State == StopState) 202 _State = DisabledState; 203} 204