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
00031
00032 #ifndef SIM_FOUNDATION_CHECK_POINT_CHECK_POINT_DATA_H
00033 #define SIM_FOUNDATION_CHECK_POINT_CHECK_POINT_DATA_H
00034
00035 #include "Utility/RuntimeError.h"
00036 #include "Sim/Foundation/Checkpoint/CheckpointMaster.h"
00037 #include "Sim/Foundation/Checkpoint/CheckpointedDataBase.h"
00038 #include "Sim/Foundation/Checkpoint/Checkpoint.h"
00039
00040 namespace Onikiri
00041 {
00042
00043 template <typename DataType>
00044 class CheckpointedData : public CheckpointedDataBase
00045 {
00046
00047 public:
00048 CheckpointedData() : m_master(0)
00049 {
00050 }
00051
00052 virtual ~CheckpointedData()
00053 {
00054 for( BackupIterator i = m_list.begin(); i != m_list.end(); ++i ){
00055 DataType* ptr = GetData(i);
00056 Destroy( ptr );
00057 }
00058 m_list.clear();
00059 }
00060
00061
00062 virtual void Initialize( CheckpointMaster* master, CheckpointMaster::Slot slot )
00063 {
00064 m_master = master;
00065 CheckpointedDataHandle handle = master->Register( this, slot );
00066 SetHandle( handle );
00067 }
00068
00069
00070 virtual void Allocate( Checkpoint* checkpoint )
00071 {
00072
00073 BackupEntry entry;
00074 entry.data = Construct();
00075 entry.valid = false;
00076
00077
00078 m_list.push_back( entry );
00079 BackupIterator i = m_list.end();
00080 --i;
00081
00082
00083 checkpoint->SetIterator( GetHandle(), i );
00084 }
00085
00086
00087 virtual void Backup( Checkpoint* checkpoint )
00088 {
00089 BackupIterator entry = GetIterator( checkpoint );
00090 entry->valid = true;
00091 *GetData( entry ) = GetCurrent();
00092 }
00093
00094
00095 virtual void Recover( Checkpoint* checkpoint )
00096 {
00097 BackupIterator entry = GetIterator( checkpoint );
00098 if( entry->valid ){
00099
00100
00101
00102
00103 GetCurrent() = *GetData( entry );
00104 }
00105 }
00106
00107
00108 virtual void Erase( Checkpoint* checkpoint )
00109 {
00110 BackupIterator i;
00111 if( GetIterator( checkpoint, &i ) ){
00112 DataType* ptr = GetData(i);
00113 if( ptr ){
00114 Destroy( ptr );
00115 }
00116 m_list.erase( i );
00117 }
00118 }
00119
00120
00121 DataType& GetCurrent() { return m_current; }
00122 const DataType& GetCurrent() const { return m_current; }
00123 DataType& operator*() { return GetCurrent(); }
00124 const DataType& operator*() const { return GetCurrent(); }
00125 DataType* operator->() { return &GetCurrent(); }
00126 const DataType* operator->() const { return &GetCurrent(); }
00127
00128 private:
00129
00130 DataType m_current;
00131 BackupList m_list;
00132
00133 CheckpointMaster* m_master;
00134
00135
00136 boost::object_pool<DataType> m_pool;
00137 void Destroy( DataType* data )
00138 {
00139 m_pool.destroy( data );
00140 }
00141 DataType* Construct()
00142 {
00143 DataType* ptr = m_pool.construct();
00144 ASSERT( ptr != NULL, "Memory allocation failed." );
00145 return ptr;
00146 }
00147
00148
00149 bool GetIterator( const Checkpoint* checkpoint, BackupIterator* iterator ) const
00150 {
00151 return checkpoint->GetIterator( GetHandle(), iterator );
00152 }
00153
00154 BackupIterator GetIterator( const Checkpoint* checkpoint ) const
00155 {
00156 BackupIterator iterator;
00157 #if ONIKIRI_DEBUG
00158 bool success = checkpoint->GetIterator( GetHandle(), &iterator );
00159 ASSERT( success, "GetIterator() failed." );
00160 #else
00161 checkpoint->GetIterator( GetHandle(), &iterator );
00162 #endif
00163 return iterator;
00164 }
00165
00166 DataType* GetData( BackupIterator i ) const
00167 {
00168 BackupEntry backup = *i;
00169 return (DataType*)(backup.data);
00170 }
00171
00172 DataType* GetData( const Checkpoint* checkpoint ) const
00173 {
00174 const BackupIterator& i = GetIterator( checkpoint );
00175 return GetData(i);
00176 }
00177 };
00178
00179 };
00180
00181 #endif // SIM_FOUNDATION_CHECK_POINT_CHECK_POINT_DATA_H
00182