From b5923a7b6f4e0f796f073aaad3253206214fc777 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 13 Jan 2014 05:42:56 -0700 Subject: [PATCH] Added "archive" project --- external/ours/library/archive/CMakeLists.txt | 9 + .../library/archive/include/Archive/Archive.h | 1 + .../archive/include/Archive/ArchiveMutex.h | 5 + .../archive/include/Archive/AutoByteStream.h | 1 + .../include/Archive/AutoDeltaByteStream.h | 1 + .../archive/include/Archive/AutoDeltaMap.h | 1 + .../include/Archive/AutoDeltaObserverOps.h | 1 + .../include/Archive/AutoDeltaPackedMap.h | 1 + .../archive/include/Archive/AutoDeltaQueue.h | 1 + .../archive/include/Archive/AutoDeltaSet.h | 2 + .../include/Archive/AutoDeltaSetObserver.h | 2 + .../Archive/AutoDeltaVariableCallback.h | 1 + .../Archive/AutoDeltaVariableObserver.h | 1 + .../archive/include/Archive/AutoDeltaVector.h | 1 + .../include/Archive/AutoDeltaVectorObserver.h | 1 + .../archive/include/Archive/ByteStream.h | 1 + .../archive/include/Archive/FirstArchive.h | 1 + .../ours/library/archive/src/CMakeLists.txt | 46 + .../archive/src/linux/ArchiveMutex.cpp | 34 + .../library/archive/src/linux/ArchiveMutex.h | 30 + .../ours/library/archive/src/shared/Archive.h | 407 +++++++++ .../archive/src/shared/AutoByteStream.cpp | 165 ++++ .../archive/src/shared/AutoByteStream.h | 683 +++++++++++++++ .../src/shared/AutoDeltaByteStream.cpp | 218 +++++ .../archive/src/shared/AutoDeltaByteStream.h | 755 +++++++++++++++++ .../library/archive/src/shared/AutoDeltaMap.h | 754 +++++++++++++++++ .../archive/src/shared/AutoDeltaObserverOps.h | 35 + .../archive/src/shared/AutoDeltaPackedMap.cpp | 32 + .../archive/src/shared/AutoDeltaPackedMap.h | 240 ++++++ .../archive/src/shared/AutoDeltaQueue.h | 408 +++++++++ .../library/archive/src/shared/AutoDeltaSet.h | 537 ++++++++++++ .../archive/src/shared/AutoDeltaSetObserver.h | 135 +++ .../src/shared/AutoDeltaVariableCallback.h | 240 ++++++ .../src/shared/AutoDeltaVariableObserver.h | 131 +++ .../archive/src/shared/AutoDeltaVector.h | 796 ++++++++++++++++++ .../src/shared/AutoDeltaVectorObserver.h | 192 +++++ .../library/archive/src/shared/ByteStream.cpp | 371 ++++++++ .../library/archive/src/shared/ByteStream.h | 408 +++++++++ .../library/archive/src/shared/FirstArchive.h | 19 + .../archive/src/win32/ArchiveMutex.cpp | 35 + .../library/archive/src/win32/ArchiveMutex.h | 27 + .../archive/src/win32/FirstArchive.cpp | 16 + 42 files changed, 6745 insertions(+) create mode 100644 external/ours/library/archive/CMakeLists.txt create mode 100644 external/ours/library/archive/include/Archive/Archive.h create mode 100644 external/ours/library/archive/include/Archive/ArchiveMutex.h create mode 100644 external/ours/library/archive/include/Archive/AutoByteStream.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaByteStream.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaMap.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaObserverOps.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaPackedMap.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaQueue.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaSet.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaSetObserver.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaVariableCallback.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaVariableObserver.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaVector.h create mode 100644 external/ours/library/archive/include/Archive/AutoDeltaVectorObserver.h create mode 100644 external/ours/library/archive/include/Archive/ByteStream.h create mode 100644 external/ours/library/archive/include/Archive/FirstArchive.h create mode 100644 external/ours/library/archive/src/CMakeLists.txt create mode 100644 external/ours/library/archive/src/linux/ArchiveMutex.cpp create mode 100644 external/ours/library/archive/src/linux/ArchiveMutex.h create mode 100644 external/ours/library/archive/src/shared/Archive.h create mode 100644 external/ours/library/archive/src/shared/AutoByteStream.cpp create mode 100644 external/ours/library/archive/src/shared/AutoByteStream.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaByteStream.cpp create mode 100644 external/ours/library/archive/src/shared/AutoDeltaByteStream.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaMap.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaObserverOps.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaPackedMap.cpp create mode 100644 external/ours/library/archive/src/shared/AutoDeltaPackedMap.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaQueue.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaSet.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaSetObserver.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaVariableCallback.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaVariableObserver.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaVector.h create mode 100644 external/ours/library/archive/src/shared/AutoDeltaVectorObserver.h create mode 100644 external/ours/library/archive/src/shared/ByteStream.cpp create mode 100644 external/ours/library/archive/src/shared/ByteStream.h create mode 100644 external/ours/library/archive/src/shared/FirstArchive.h create mode 100644 external/ours/library/archive/src/win32/ArchiveMutex.cpp create mode 100644 external/ours/library/archive/src/win32/ArchiveMutex.h create mode 100644 external/ours/library/archive/src/win32/FirstArchive.cpp diff --git a/external/ours/library/archive/CMakeLists.txt b/external/ours/library/archive/CMakeLists.txt new file mode 100644 index 00000000..f517094e --- /dev/null +++ b/external/ours/library/archive/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8) + +project(archive) + +if(WIN32) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif() + +add_subdirectory(src) diff --git a/external/ours/library/archive/include/Archive/Archive.h b/external/ours/library/archive/include/Archive/Archive.h new file mode 100644 index 00000000..069a3dc2 --- /dev/null +++ b/external/ours/library/archive/include/Archive/Archive.h @@ -0,0 +1 @@ +#include "../../src/shared/Archive.h" diff --git a/external/ours/library/archive/include/Archive/ArchiveMutex.h b/external/ours/library/archive/include/Archive/ArchiveMutex.h new file mode 100644 index 00000000..36d10b27 --- /dev/null +++ b/external/ours/library/archive/include/Archive/ArchiveMutex.h @@ -0,0 +1,5 @@ +#ifdef WIN32 +#include "../../src/win32/ArchiveMutex.h" +#else +#include "../../src/linux/ArchiveMutex.h" +#endif diff --git a/external/ours/library/archive/include/Archive/AutoByteStream.h b/external/ours/library/archive/include/Archive/AutoByteStream.h new file mode 100644 index 00000000..ef4aab99 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoByteStream.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoByteStream.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaByteStream.h b/external/ours/library/archive/include/Archive/AutoDeltaByteStream.h new file mode 100644 index 00000000..5a4c957c --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaByteStream.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaByteStream.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaMap.h b/external/ours/library/archive/include/Archive/AutoDeltaMap.h new file mode 100644 index 00000000..d5ee887e --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaMap.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaMap.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaObserverOps.h b/external/ours/library/archive/include/Archive/AutoDeltaObserverOps.h new file mode 100644 index 00000000..cd3eaab9 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaObserverOps.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaObserverOps.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaPackedMap.h b/external/ours/library/archive/include/Archive/AutoDeltaPackedMap.h new file mode 100644 index 00000000..d9576abf --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaPackedMap.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaPackedMap.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaQueue.h b/external/ours/library/archive/include/Archive/AutoDeltaQueue.h new file mode 100644 index 00000000..25571f51 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaQueue.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaQueue.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaSet.h b/external/ours/library/archive/include/Archive/AutoDeltaSet.h new file mode 100644 index 00000000..bfb615f1 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaSet.h @@ -0,0 +1,2 @@ +#include "../../src/shared/AutoDeltaSet.h" + diff --git a/external/ours/library/archive/include/Archive/AutoDeltaSetObserver.h b/external/ours/library/archive/include/Archive/AutoDeltaSetObserver.h new file mode 100644 index 00000000..5317a58c --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaSetObserver.h @@ -0,0 +1,2 @@ +#include "../../src/shared/AutoDeltaSetObserver.h" + diff --git a/external/ours/library/archive/include/Archive/AutoDeltaVariableCallback.h b/external/ours/library/archive/include/Archive/AutoDeltaVariableCallback.h new file mode 100644 index 00000000..fe924c32 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaVariableCallback.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaVariableCallback.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaVariableObserver.h b/external/ours/library/archive/include/Archive/AutoDeltaVariableObserver.h new file mode 100644 index 00000000..c16dfc81 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaVariableObserver.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaVariableObserver.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaVector.h b/external/ours/library/archive/include/Archive/AutoDeltaVector.h new file mode 100644 index 00000000..47c8c027 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaVector.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaVector.h" diff --git a/external/ours/library/archive/include/Archive/AutoDeltaVectorObserver.h b/external/ours/library/archive/include/Archive/AutoDeltaVectorObserver.h new file mode 100644 index 00000000..2e923e60 --- /dev/null +++ b/external/ours/library/archive/include/Archive/AutoDeltaVectorObserver.h @@ -0,0 +1 @@ +#include "../../src/shared/AutoDeltaVectorObserver.h" diff --git a/external/ours/library/archive/include/Archive/ByteStream.h b/external/ours/library/archive/include/Archive/ByteStream.h new file mode 100644 index 00000000..94bf49b6 --- /dev/null +++ b/external/ours/library/archive/include/Archive/ByteStream.h @@ -0,0 +1 @@ +#include "../../src/shared/ByteStream.h" diff --git a/external/ours/library/archive/include/Archive/FirstArchive.h b/external/ours/library/archive/include/Archive/FirstArchive.h new file mode 100644 index 00000000..fe1c8db2 --- /dev/null +++ b/external/ours/library/archive/include/Archive/FirstArchive.h @@ -0,0 +1 @@ +#include "../../src/shared/FirstArchive.h" diff --git a/external/ours/library/archive/src/CMakeLists.txt b/external/ours/library/archive/src/CMakeLists.txt new file mode 100644 index 00000000..b33f804f --- /dev/null +++ b/external/ours/library/archive/src/CMakeLists.txt @@ -0,0 +1,46 @@ + + +set(SHARED_SOURCES + shared/Archive.h + shared/AutoByteStream.cpp + shared/AutoByteStream.h + shared/AutoDeltaByteStream.cpp + shared/AutoDeltaByteStream.h + shared/AutoDeltaMap.h + shared/AutoDeltaObserverOps.h + shared/AutoDeltaPackedMap.cpp + shared/AutoDeltaPackedMap.h + shared/AutoDeltaQueue.h + shared/AutoDeltaSet.h + shared/AutoDeltaSetObserver.h + shared/AutoDeltaVariableCallback.h + shared/AutoDeltaVariableObserver.h + shared/AutoDeltaVector.h + shared/AutoDeltaVectorObserver.h + shared/ByteStream.cpp + shared/ByteStream.h + shared/FirstArchive.h +) + +if(WIN32) + set(PLATFORM_SOURCES + win32/ArchiveMutex.cpp + win32/ArchiveMutex.h + ) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32) +else() + set(PLATFORM_SOURCES + linux/ArchiveMutex.cpp + linux/ArchiveMutex.h + ) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/linux) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/shared) + +add_library(archive + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) diff --git a/external/ours/library/archive/src/linux/ArchiveMutex.cpp b/external/ours/library/archive/src/linux/ArchiveMutex.cpp new file mode 100644 index 00000000..30a6b10f --- /dev/null +++ b/external/ours/library/archive/src/linux/ArchiveMutex.cpp @@ -0,0 +1,34 @@ +// ====================================================================== +// +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + + +#include "ArchiveMutex.h" + +namespace Archive +{ + +ArchiveMutex::ArchiveMutex() +{ + pthread_mutex_init(&mutex, 0); +} + +ArchiveMutex::~ArchiveMutex() +{ + pthread_mutex_destroy(&mutex); +} + +void ArchiveMutex::enter() +{ + pthread_mutex_lock(&mutex); +} + +void ArchiveMutex::leave() +{ + pthread_mutex_unlock(&mutex); +} + +} diff --git a/external/ours/library/archive/src/linux/ArchiveMutex.h b/external/ours/library/archive/src/linux/ArchiveMutex.h new file mode 100644 index 00000000..d676b69c --- /dev/null +++ b/external/ours/library/archive/src/linux/ArchiveMutex.h @@ -0,0 +1,30 @@ +#ifndef _ArchiveMutex_H +#define _ArchiveMutex_H + +#include + +namespace Archive +{ + + class ArchiveMutex + { + + public: + ArchiveMutex(); + ~ArchiveMutex(); + void enter(); + void leave(); + + pthread_mutex_t &getInternalMutex() { return mutex; } + private: + ArchiveMutex(const ArchiveMutex &o); + ArchiveMutex &operator =(const ArchiveMutex &o); + + pthread_mutex_t mutex; + + }; +}; + + + +#endif diff --git a/external/ours/library/archive/src/shared/Archive.h b/external/ours/library/archive/src/shared/Archive.h new file mode 100644 index 00000000..2921d66f --- /dev/null +++ b/external/ours/library/archive/src/shared/Archive.h @@ -0,0 +1,407 @@ +#ifndef _Archive_H +#define _Archive_H + +//--------------------------------------------------------------------- + +#include "ByteStream.h" +#include +#include +#include +#include + +//--------------------------------------------------------------------- + +namespace Archive { + +//--------------------------------------------------------------------- + + +inline void get(ReadIterator & source, double & target) +{ + source.get(&target, 8); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, float & target) +{ + source.get(&target, 4); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, unsigned long int & target) +{ + source.get(&target, 4); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, signed long int & target) +{ + source.get(&target, 4); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, unsigned int & target) +{ + source.get(&target, 4); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, signed int & target) +{ + source.get(&target, 4); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, unsigned short int & target) +{ + source.get(&target, 2); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, signed short int & target) +{ + source.get(&target, 2); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, unsigned char & target) +{ + source.get(&target, 1); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, signed char & target) +{ + source.get(&target, 1); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, std::string & target) +{ + unsigned short len; + unsigned int size; + get(source, len); + if (len < 65535) + size = len; + else + get(source, size); + const char * c = reinterpret_cast(source.getBuffer()); + target = std::string(c, size); + source.advance(size); +} + +//--------------------------------------------------------------------- + +inline void get(ReadIterator & source, bool & target) +{ + source.get(&target, 1); +} + +//----------------------------------------------------------------------- + +inline void get(ReadIterator & source, ByteStream & target) +{ + unsigned int s; + get(source, s); + target.put(source.getBuffer(), s); + source.advance(s); +} + +//---------------------------------------------------------------------- + +template inline void get(ReadIterator & source, std::pair & target) +{ + get(source, target.first); + get(source, target.second); +} + +//--------------------------------------------------------------------- + +template inline void get(ReadIterator & source, std::vector& target) +{ + target.clear(); + signed int length = 0; + source.get(&length, 4); + A temp; + for(int i = 0; i < length; ++i) + { + get(source, temp); + target.push_back(temp); + } +} + +//----------------------------------------------------------------------- + +template inline void get(ReadIterator & source, std::set& target) +{ + target.clear(); + signed int length = 0; + source.get(&length, 4); + A temp; + for(int i = 0; i < length; ++i) + { + get(source, temp); + target.insert(temp); + } +} + +//----------------------------------------------------------------------- + +template inline void get(ReadIterator & source, std::deque& target) +{ + target.clear(); + signed int length = 0; + source.get(&length, 4); + A temp; + for(int i = 0; i < length; ++i) + { + get(source, temp); + target.push_back(temp); + } +} + +//----------------------------------------------------------------------- + +template inline void get_ptr(ReadIterator & source, std::vector& target) +{ + target.clear(); + signed int length = 0; + source.get(&length, 4); +// A temp; + for(int i = 0; i < length; ++i) + { + A * temp = new A; + get(source, temp); + target.push_back(temp); + } +} + +//----------------------------------------------------------------------- + +template inline void get(ReadIterator & source, std::map & target) +{ + size_t numKeys; + get(source, numKeys); + size_t i; + for(i = 0; i < numKeys; ++i) + { + Key k; + get(source, k); + Value v; + get(source, v); + target[k] = v; + } +} + +//--------------------------------------------------------------------- + +template inline void get(ReadIterator & source, A * target, int length) +{ + for(int i = 0; i < length; ++i) + { + get(source, target[i]); + } +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const double & source) +{ + target.put(&source, 8); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const float & source) +{ + target.put(&source, 4); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const unsigned long int & source) +{ + target.put(&source, 4); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const signed long int & source) +{ + target.put(&source, 4); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const unsigned int & source) +{ + target.put(&source, 4); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const signed int & source) +{ + target.put(&source, 4); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const unsigned short int & source) +{ + target.put(&source, 2); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const signed short int & source) +{ + target.put(&source, 2); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const unsigned char & source) +{ + target.put(&source, 1); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const signed char & source) +{ + target.put(&source, 1); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const char & source) +{ + target.put(&source, 1); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const std::string & source) +{ + if (source.size() < 65535) + { + unsigned short len = static_cast(source.size()); + put(target, len); + } + else + { + unsigned short len = static_cast(65535); + put(target, len); + unsigned int size = source.size(); + put(target, size); + } + target.put(source.data(), source.size()); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, const bool & source) +{ + target.put(&source, 1); +} + +//--------------------------------------------------------------------- + +inline void put(ByteStream & target, Archive::ReadIterator & source) +{ + put(target, source.getSize()); + target.put(source.getBuffer(), source.getSize()); + source.advance(source.getSize()); +} + +//----------------------------------------------------------------------- + +inline void put(ByteStream & target, const ByteStream & source) +{ + put(target, source.begin().getSize()); + target.put(source.begin().getBuffer(), source.begin().getSize()); +} + +//---------------------------------------------------------------------- + +template inline void put(ByteStream & target, const std::pair & source) +{ + put(target, source.first); + put(target, source.second); +} + +//--------------------------------------------------------------------- + +template inline void put(ByteStream & target, const std::vector & source) +{ + signed int length = source.size(); + target.put(&length, 4); + for(int i = 0; i < length; ++i) + { + put(target, source[i]); + } +} + +//----------------------------------------------------------------------- + +template inline void put(ByteStream & target, const std::set & source) +{ + signed int length = source.size(); + target.put(&length, 4); + for (typename std::set::const_iterator i = source.begin(); i != source.end(); ++i) + put(target, *i); +} + +//----------------------------------------------------------------------- + +template inline void put(ByteStream & target, const std::deque & source) +{ + signed int length = source.size(); + target.put(&length, 4); + for(int i = 0; i < length; ++i) + { + put(target, source[i]); + } +} + +//----------------------------------------------------------------------- + +template inline void put(ByteStream & target, const std::map & source) +{ + size_t numKeys = source.size(); + put(target, numKeys); + for (typename std::map::const_iterator i = source.begin(); i != source.end(); ++i) + { + put(target, i->first); + put(target, i->second); + } +} + +//--------------------------------------------------------------------- + +template inline void put(ByteStream & target, const A * source, int length) +{ + for(int i = 0; i < length; ++i) + { + put(target, source[i]); + } +} + +//--------------------------------------------------------------------- + +}//namespace Archive + +//--------------------------------------------------------------------- + +#endif // _Archive_H diff --git a/external/ours/library/archive/src/shared/AutoByteStream.cpp b/external/ours/library/archive/src/shared/AutoByteStream.cpp new file mode 100644 index 00000000..d62be53b --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoByteStream.cpp @@ -0,0 +1,165 @@ + +//--------------------------------------------------------------------- +#include "FirstArchive.h" + +#include "Archive.h" +#include "AutoByteStream.h" +#include "ByteStream.h" + +namespace Archive { + +//--------------------------------------------------------------------- +/** + @brief construct a AutoByteStream + + Invokes the default constructor for the members vector + + @see ByteStream + + @author Justin Randall +*/ +AutoByteStream::AutoByteStream() : +members() +{ +} + +//--------------------------------------------------------------------- +/** + @brief destroy the AutoByteStream + + Doesn't do anything special. + + @see ByteStream + + @author Justin Randall +*/ +AutoByteStream::~AutoByteStream() +{ +} + +//--------------------------------------------------------------------- +/** + @brief Add a AutoVariable to a list of data to be automatically + packed or unpacked. + + Add the instance of a AutoVariableBase derivative to the + AutoByteStream's list of values to be packed and unpacked + automatically. The AutoByteStream will handle correct packing + and unpacking order as long as the variables are added in + order. Typically, these variables are added during construction + of some AutoByteStream derived class. + + Once a variable has been added, it cannot be removed. + + @param newVariable A reference to the instance of the + AutoVariableBase that will be added to the + AutoByteStream's list of tracked values. + + @see AutoByteStream + @see AutoVariableBase + @see AutoVariable + @see ByteStream + + @author Justin Randall +*/ +void AutoByteStream::addVariable(AutoVariableBase & newVariable) +{ + members.push_back(&newVariable); +} +//----------------------------------------------------------------------- + +const unsigned int AutoByteStream::getItemCount() const +{ + return members.size(); +} + +//--------------------------------------------------------------------- +/** + @brief Pack the values (AutoVariableBase or derivatives) into the + ByteStream Buffer + + When the pack method is invoked, all of the members added with + addVariable are placed, in the order they were added, into the + ByteStream's buffer. The ByteStream returns a reference to itself + after the pack operation has completed. + + @see AutoVariableBase::pack + @see ByteStream::pack + @see ByteStream + @see AutoByteStream + @see AutoVariable + + @return a reference to this AutoByteStream + + @author Justin Randall +*/ +void AutoByteStream::pack(ByteStream & target) const +{ + std::vector::const_iterator i; + unsigned short packedSize=static_cast(members.size()); + Archive::put(target,packedSize); + for(i = members.begin(); i != members.end(); ++i) + { + (*i)->pack(target); + } +} + +//--------------------------------------------------------------------- +/** + @brief Restore values from an ByteStream buffer + + Values are restored from the source ByteStream's buffer in the order + that this ByteStream's members were added (using addVariable). + + @param source The ByteStream containing the source data starting at + the ByteStream's current read position. + + @see AutoByteStream::pack + @see AutoByteStream + @see ByteStream::unpack + @see ByteStream::pack + @see ByteStream + @see AutoVariableBase::unpack + @see AutoVariableBase + + @author Justin Randall +*/ +void AutoByteStream::unpack(ReadIterator & source) +{ + std::vector::iterator i; + unsigned short packedSize; + Archive::get(source,packedSize); + for(i = members.begin(); i != members.end(); ++i) + { + (*i)->unpack(source); + } +} + +//--------------------------------------------------------------------- +/** + @brief construct an AutoVariableBase object + + The AutoVariableBase class is pure virtual. This is never directly + invoked. + + @author Justin Randall +*/ +AutoVariableBase::AutoVariableBase() +{ +} + +//--------------------------------------------------------------------- +/** + @brief AutoVariableBase dtor + + Defined, but is pure virtual + + @author Justin Randall +*/ +AutoVariableBase::~AutoVariableBase() +{ +} + +//---------------------------------------------------------------------- + +}//namespace Archive diff --git a/external/ours/library/archive/src/shared/AutoByteStream.h b/external/ours/library/archive/src/shared/AutoByteStream.h new file mode 100644 index 00000000..21eb963f --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoByteStream.h @@ -0,0 +1,683 @@ + +#ifndef _INCLUDED_AutoByteStream_H +#define _INCLUDED_AutoByteStream_H + +//--------------------------------------------------------------------- +#pragma warning ( disable : 4786) + +#include "Archive.h" +#include +#include +#include + +namespace Archive { +//--------------------------------------------------------------------- + +class ByteStream; +class AutoVariableBase; + +//--------------------------------------------------------------------- +/** + @brief AutoAchive is a specialization of ByteStream that automates packing + and unpacking. + + To use a AutoByteStream, the client declares AutoVariables for + members it owns and wants to persist. If the client class derives + from some parent which does not provide Auto variables: + + Declare a AutoVariable that shadows the parent class' normal + integral type, override pack and unpack. During the pack + operation, the subclass sets the AutoVariable shadowing the + parent value, then invokes AutoByteStream::pack(). Durin the + unpack operation, invoke AutoByteStream::unpack(), then invoke + the parent's setter to assign the parent's value to the + AutoVariable's value. + + Example Usage: + \code + class MyAutoByteStream : public AutoByteStream + { + public: + MyAutoByteStream(); + ~MyAutoByteStream() {}; + + const float getFloatValue() const; + const int getIntValue() const; + void setValue(const float value); + void setValue(const int value); + + private: + AutoVariable i; + }; + + MyAutoByteStream::MyAutoByteStream() : + i(0) + { + addVariable(i); + } + + const int MyAutoByteStream::getIntValue() const + { + return i; // conversion take care of in the AutoVariable template + } + + void MyAutoByteStream::setValue(const int newValue) + { + i = newValue; + } + + void foo() + { + MyAutoArchvie a; + + a.setValue(42); + a.setValue(3.1415f); + receiveNetworkMessage(a.pack()); + } + + void receiveNetworkMessage(const ByteStream & source) + { + MyAutoByteStream b + + b << source; + + assert(b.getIntValue() == 42); + assert(b.getFloatValue() == 3.1415f); + } + \endcode + + @see AutoVariable + + @author Justin Randall +*/ +class AutoByteStream +{ +public: + AutoByteStream(); + virtual ~AutoByteStream(); + void addVariable(AutoVariableBase & newVariable); + virtual const unsigned int getItemCount() const; + virtual void pack(ByteStream & target) const; + virtual void unpack(ReadIterator & source); +protected: + /** + @brief a list of member variables that are tracked by this + AutoByteStream object + */ + std::vector members; +private: + /** disabled */ + AutoByteStream(const AutoByteStream & source); +}; + +//--------------------------------------------------------------------- +/** + @brief A AutoVariableBase is an abstract class which defines a pack + and unpack interface for the AutoByteStream. + + AutoVariables derive from this class. + + @see AutoVariable + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +class AutoVariableBase +{ +public: + AutoVariableBase(); + virtual ~AutoVariableBase(); + /** pure virtual */ + virtual void pack(ByteStream & target) const = 0; + + /** pure virtual */ + virtual void unpack(ReadIterator & source) = 0; +}; + + +//---------------------------------------------------------------------- + +inline void get(ReadIterator &source, AutoVariableBase & target) +{ + target.unpack (source); +} + +//---------------------------------------------------------------------- + +inline void put(ByteStream &target, const AutoVariableBase & source) +{ + source.pack (target); +} + +//----------------------------------------------------------------------- +/** + A stand-alone, authoritative Auto variable template + + The AutoVariable contains an instance of a ValueType. It behaves + much like the ValueType it encapsulates, but also provides a + serialization interface for AutoByteStreams. + + The use of a AutoVariable is intended to behave similarly to + the actual ValueType it tracks, adding features for automatic + archival and retrieval. + + A AutoVariable template should be used in a AutoByteStream + derived class to automatically pack and unpack data when the + ByteStream is packed or unpacked. + + Refer to AutoByteStream for example useage of a AutoVariable. + + @see AutoByteStream + @see AutoVariableBase + + @author Justin Randall +*/ +template +class AutoVariable : public AutoVariableBase +{ +public: + AutoVariable(); + explicit AutoVariable(const ValueType & source); + virtual ~AutoVariable(); + + const ValueType & get() const; + virtual void pack(ByteStream & target) const; + void set(const ValueType & rhs); + virtual void unpack(ReadIterator & source); + +private: + ValueType value; +}; + +//--------------------------------------------------------------------- +/** + @brief construct an AutoVariable +*/ +template +AutoVariable::AutoVariable() : +AutoVariableBase(), +value() +{ +} + +//--------------------------------------------------------------------- +/** + ValueType copy constructor. + + Motivation: Provide an implicit conversion for the AutoVariable + that mimicks the ValueType it represents. + + Invoking this copy constructor merely assigns the source value + to the AutoVariable value member. + + @param source The source value which will + employ ValueType's assignment + operator to set + AutoVariable::value to the + source value. + + @author Justin Randall +*/ +template +AutoVariable::AutoVariable(const ValueType & source) : +AutoVariableBase(), +value(source) +{ +} + +//--------------------------------------------------------------------- +/** + @brief Destroy the AutoVariable object + + Doesn't do anything special + + @author Justin Randall +*/ +template +AutoVariable::~AutoVariable() +{ +} + +//--------------------------------------------------------------------- +/** + @brief Retrieve the current value of the AutoVariable + + @return A const reference to the current value + + Example: + \code + AutoVariable i; + i.set(10); + int j = i.get(); + \endcode + + @author Justin Randall + + @see AutoVariableBase +*/ +template +const ValueType & AutoVariable::get() const +{ + return value; +} + +//--------------------------------------------------------------------- +/** + Pack the current value of the AutoVariable + + The current value of the AutoVariable is packed at the write + position of the target ByteStream. + + The target ByteStream is typically a AutoByteStream, as it has + protected access to the AutoVariable::pack() method. + + @param target an ByteStream to receive the value at its + current write position + + @see AutoVariable + @see AutoVariableBase + @see AutoByteStream + + @author Justin Randall +*/ +template +void AutoVariable::pack(ByteStream & target) const +{ + Archive::put(target, value); +} + +//--------------------------------------------------------------------- +/** + @brief set the current value of a AutoVariable + + @param rhs the new value + + @author Justin Randall +*/ +template +void AutoVariable::set(const ValueType & rhs) +{ + value = rhs; +} + +//--------------------------------------------------------------------- +/** + Unpack a value from a source ByteStream and set the current value. + + A new value is extracted from the source ByteStream at its current + read position and applied to the AutoVariable value member. + + The source ByteStream is typically a AutoByteStream, as it has + protected access to the AutoVariable::unpack() method. + + @param source The ByteStream supplying the new + value for the + + @see AutoByteStream + @see AutoVariableBase + + @author Justin Randall +*/ +template +void AutoVariable::unpack(ReadIterator & source) +{ + Archive::get(source, value); +} + +//----------------------------------------------------------------------- +/** + @brief Like autovariable, but tracks an array (vector) of values + + If an array needs to be ByteStreamd automatically, it must be + a vector. + +*/ +template +class AutoArray : public AutoVariableBase +{ +public: + AutoArray(); + AutoArray(const AutoArray & source); + ~AutoArray(); + + typedef std::vector DataVector; + std::vector & get(); + const std::vector & get() const; + void set(const std::vector & source); + + virtual void pack(ByteStream & target) const; + virtual void unpack(ReadIterator & source); + +private: + std::vector array; +}; + +//----------------------------------------------------------------------- +/** + @brief AutoArray ctor + + Instantiate an AutoArray of ValueType objects + + @author Justin Randall +*/ +template +inline AutoArray::AutoArray() +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoArray copy constructor + + Deep copy an AutoArray of ValueType objects + + @author Justin Randall +*/ +template +inline AutoArray::AutoArray(const AutoArray & source) : +array(source.array) +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoArray dtor + + Doesn't do anything special + + @author Justin Randall +*/ +template +inline AutoArray::~AutoArray() +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoArray accessor routine + + @return a const reference to a vector of ValueType objects + + @author Justin Randall +*/ +template +inline const std::vector & AutoArray::get() const +{ + return array; +} + +//----------------------------------------------------------------------- +/** + @brief AutoArray accessor routine + + @return a reference to a vector of ValueType objects + + @author Justin Randall +*/ +template +inline std::vector & AutoArray::get() +{ + return array; +} + +//----------------------------------------------------------------------- +/** + @brief AutoArray accessor routine + + @param source a const reference to an STL vector of ValueType objects + which are deep copied into this AutoArray's vector of + ValueType objects + + @author Justin Randall +*/ +template +inline void AutoArray::set(const std::vector & source) +{ + array = source; +} + +//----------------------------------------------------------------------- +/** + @brief pack this AutoArray into an Archive::ByteStream + + The Archive::ByteStream receives an integer indicating the number + of ValueType objects contained by the AutoArray, followed by each + element of the AutoArray. The data is written at the Archive::ByteStream + object's current write position. + + @param target The Archive::ByteStream object that will receive the + AutoArray data. + + @see Archive::ByteStream + @see unpack + + @author Justin Randall +*/ +template +inline void AutoArray::pack(Archive::ByteStream & target) const +{ + unsigned int arraySize = array.size(); + Archive::put(target, arraySize); + + typename std::vector::const_iterator i; + for(i = array.begin(); i != array.end(); ++i) + { + Archive::put(target, (*i)); + } +} + +//----------------------------------------------------------------------- +/** + @brief retrieve AutoArray elements from a source Archive::ByteStream + object. + + This method will reconstruct a populated ValueArray from an + Archive::ByteStream object that had an AutoArray of the same + ValueType written at the ByteStream's current read position. + + First an integer indicating the number of objects in the stream + is retrieved, followed by values for each ValueType object that + was put into the Archive::ByteStream. + + @param source The source Archive::ByteStream containing AutoArray + data at it's current read position. + + @see Archive::ByteStrea + @see pack + + @author Justin Randall +*/ +template +inline void AutoArray::unpack(Archive::ReadIterator & source) +{ + unsigned int arraySize; + Archive::get(source, arraySize); + ValueType v; + + for(unsigned int i = 0; i < arraySize; ++i) + { + Archive::get(source, v); + array.push_back(v); + } +} + +//----------------------------------------------------------------------- +/** + @brief Like autovariable, but tracks an array (list) of values + +*/ +template +class AutoList : public AutoVariableBase +{ +public: + AutoList(); + AutoList(const AutoList & source); + ~AutoList(); + + typedef std::list DataList; + std::list & get(); + const std::list & get() const; + void set(const std::list & source); + + virtual void pack(ByteStream & target) const; + virtual void unpack(ReadIterator & source); + +private: + std::list theList; +}; + +//----------------------------------------------------------------------- +/** + @brief AutoList ctor + + Instantiate an AutoList of ValueType objects + + @author Justin Randall +*/ +template +inline AutoList::AutoList() +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoList copy constructor + + Deep copy an AutoList of ValueType objects + + @author Justin Randall +*/ +template +inline AutoList::AutoList(const AutoList & source) : +theList(source.theList) +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoList dtor + + Doesn't do anything special + + @author Justin Randall +*/ +template +inline AutoList::~AutoList() +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoList accessor routine + + @return a const reference to a list of ValueType objects + + @author Justin Randall +*/ +template +inline const std::list & AutoList::get() const +{ + return theList; +} + +//----------------------------------------------------------------------- +/** + @brief AutoList accessor routine + + @return a reference to a list of ValueType objects + + @author Justin Randall +*/ +template +inline std::list & AutoList::get() +{ + return theList; +} + +//----------------------------------------------------------------------- +/** + @brief AutoList accessor routine + + @param source a const reference to an STL list of ValueType objects + which are deep copied into this AutoList's list of + ValueType objects + + @author Justin Randall +*/ +template +inline void AutoList::set(const std::list & source) +{ + theList = source; +} + +//----------------------------------------------------------------------- +/** + @brief pack this AutoList into an Archive::ByteStream + + The Archive::ByteStream receives an integer indicating the number + of ValueType objects contained by the AutoList, followed by each + element of the AutoList. The data is written at the Archive::ByteStream + object's current write position. + + @param target The Archive::ByteStream object that will receive the + AutoList data. + + @see Archive::ByteStream + @see unpack + + @author Justin Randall +*/ +template +inline void AutoList::pack(Archive::ByteStream & target) const +{ + unsigned int arraySize = theList.size(); + Archive::put(target, arraySize); + + typename std::list::const_iterator i; + for(i = theList.begin(); i != theList.end(); ++i) + { + Archive::put(target, (*i)); + } +} + +//----------------------------------------------------------------------- +/** + @brief retrieve AutoList elements from a source Archive::ByteStream + object. + + This method will reconstruct a populated ValueArray from an + Archive::ByteStream object that had an AutoList of the same + ValueType written at the ByteStream's current read position. + + First an integer indicating the number of objects in the stream + is retrieved, followed by values for each ValueType object that + was put into the Archive::ByteStream. + + @param source The source Archive::ByteStream containing AutoList + data at it's current read position. + + @see Archive::ByteStrea + @see pack + + @author Justin Randall +*/ +template +inline void AutoList::unpack(Archive::ReadIterator & source) +{ + unsigned int arraySize; + Archive::get(source, arraySize); + ValueType v; + + for(unsigned int i = 0; i < arraySize; ++i) + { + Archive::get(source, v); + theList.push_back(v); + } +} + +//--------------------------------------------------------------------- + +}//namespace Archive + +#endif // _INCLUDED_AutoByteStream_H diff --git a/external/ours/library/archive/src/shared/AutoDeltaByteStream.cpp b/external/ours/library/archive/src/shared/AutoDeltaByteStream.cpp new file mode 100644 index 00000000..2fde39eb --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaByteStream.cpp @@ -0,0 +1,218 @@ + +//----------------------------------------------------------------------- +#include "FirstArchive.h" + +#include "Archive.h" +#include "ByteStream.h" + +#ifdef _WIN32 +#pragma warning (disable: 4702) +#endif + +#include "AutoDeltaByteStream.h" + +namespace Archive { + +//----------------------------------------------------------------------- + +OnDirtyCallbackBase::OnDirtyCallbackBase() +{ +} + +//----------------------------------------------------------------------- + +OnDirtyCallbackBase::~OnDirtyCallbackBase() +{ +} + +//----------------------------------------------------------------------- +/** + @brief construct a AutoDeltaByteStream + + @author Justin Randall +*/ +AutoDeltaByteStream::AutoDeltaByteStream() : + AutoByteStream(), + dirtyList(), + onDirtyCallback(0) +{ +} + +//----------------------------------------------------------------------- +/** + @brief destroy a AutoDeltaByteStream + + @author Justin Randall +*/ +AutoDeltaByteStream::~AutoDeltaByteStream() +{ + onDirtyCallback = 0; +} + +//----------------------------------------------------------------------- + +void AutoDeltaByteStream::addOnDirtyCallback(OnDirtyCallbackBase * newCallback) +{ + onDirtyCallback = newCallback; +} + +//----------------------------------------------------------------------- +/** + @brief add a member to the dirty list + + This protected support method helps a AutoDeltaByteStream identify + dirty variables. + + @author Justin Randall +*/ +void AutoDeltaByteStream::addToDirtyList(AutoDeltaVariableBase * var) +{ + dirtyList.insert(var); //lint !e534 // ignoring iterator returned from insert + if (onDirtyCallback) + { + onDirtyCallback->onDirty(); + } +} + +//--------------------------------------------------------------------- +/** + @brief Add a new variable to the AutoDeltaByteStream. + + This method leverages the AutoByteStream member list ot identify + values tracked by the AutoByteStream. Additionally, the variable + index is set so that it may identify itself when it is used + in a non-const manner, and it receives a reference to it's owner + AutoDeltaByteStream. + + @author Justin Randall +*/ +void AutoDeltaByteStream::addVariable(AutoDeltaVariableBase & var) +{ + var.setIndex(static_cast(members.size())); + var.setOwner(this); + AutoByteStream::addVariable(var); +} + +//--------------------------------------------------------------------- + +const unsigned int AutoDeltaByteStream::getItemCount() const +{ + unsigned short int count = 0; + + if (!dirtyList.empty()) + { + for (std::set::const_iterator i = dirtyList.begin(); i != dirtyList.end(); ++i) + { + AutoDeltaVariableBase * const v = reinterpret_cast(*i); + if (v->isDirty()) + ++count; + } + } + + return count; +} + +//----------------------------------------------------------------------- +/** + @brief Pack values that have changed since the last time deltas + were collected. + + @author Justin Randall +*/ +void AutoDeltaByteStream::packDeltas(ByteStream & target) const +{ + unsigned short int const count = static_cast(getItemCount()); + + // place count in archive + Archive::put(target, count); + + if (count > 0) + { + for (std::set::const_iterator i = dirtyList.begin(); i != dirtyList.end(); ++i) + { + AutoDeltaVariableBase * const v = reinterpret_cast(*i); + if (v->isDirty()) + { + put(target, v->getIndex()); + v->packDelta(target); + } + } + } + + dirtyList.clear(); +} + +//----------------------------------------------------------------------- + +void AutoDeltaByteStream::clearDeltas() const +{ + if (!dirtyList.empty()) + { + for (std::set::const_iterator i = dirtyList.begin(); i != dirtyList.end(); ++i) + { + AutoDeltaVariableBase * const v = reinterpret_cast(*i); + v->clearDelta(); + } + dirtyList.clear(); + } +} + +//----------------------------------------------------------------------- + +void AutoDeltaByteStream::removeOnDirtyCallback() +{ + onDirtyCallback = 0; +} + +//--------------------------------------------------------------------- +/** + @brief receive a delta ByteStream and apply the new deltas. + + Receive a delta ByteStream and apply the new deltas to the local + object. The ByteStream MUST be created by another AutoDeltaByteStream! + + @author Justin Randall +*/ +void AutoDeltaByteStream::unpackDeltas(ReadIterator & source) +{ + unsigned short int index; + unsigned short int count; + Archive::get(source, count); + + while (source.getSize()) + { + get(source, index); + AutoDeltaVariableBase * const v = reinterpret_cast(members[index]); + v->unpackDelta(source); + } +} + +//----------------------------------------------------------------------- +/** + @brief constructor for an abstract AutoDeltaVariableBase object + + @author Justin Randall +*/ +AutoDeltaVariableBase::AutoDeltaVariableBase() : + AutoVariableBase(), + index(0), + owner(0) +{ +} + +//----------------------------------------------------------------------- +/** + @brief desctructor for a AutoDeltaVariableBase or derivative + object. + + @author Justin Randall +*/ +AutoDeltaVariableBase::~AutoDeltaVariableBase() +{ + owner = 0; +} + +//----------------------------------------------------------------------- + +}//namespace Archive + diff --git a/external/ours/library/archive/src/shared/AutoDeltaByteStream.h b/external/ours/library/archive/src/shared/AutoDeltaByteStream.h new file mode 100644 index 00000000..e8821a74 --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaByteStream.h @@ -0,0 +1,755 @@ + +#ifndef _INCLUDED_AutoDeltaByteStream_H +#define _INCLUDED_AutoDeltaByteStream_H + +//----------------------------------------------------------------------- + +#if WIN32 +#pragma warning ( disable : 4786 ) +#pragma warning ( disable : 4800 ) + +#endif + +#include +#include "AutoByteStream.h" +#include "ByteStream.h" +#include +#include + +namespace Archive { + +class AutoDeltaVariableBase; + +class OnDirtyCallbackBase +{ +public: + OnDirtyCallbackBase(); + virtual ~OnDirtyCallbackBase() = 0; + virtual void onDirty() = 0; +private: + OnDirtyCallbackBase(const OnDirtyCallbackBase &); + OnDirtyCallbackBase & operator = (const OnDirtyCallbackBase &); +}; + +template +class OnDirtyCallback : public OnDirtyCallbackBase +{ +public: + OnDirtyCallback() : + owner(0), + callback(0) + { + } + + OnDirtyCallback(ObjectType &o, void (ObjectType::*onDirty)()) : + owner(&o), + callback(onDirty) + { + } + + virtual ~OnDirtyCallback() + { + } + + void set(ObjectType &o, void (ObjectType::*onDirty)()) + { + owner = &o; + callback = onDirty; + } + + virtual void onDirty() + { + if (owner && callback) + ((*owner).*callback)(); + } + +private: + OnDirtyCallback(const OnDirtyCallback &); + OnDirtyCallback & operator = (const OnDirtyCallback &); + +private: + ObjectType *owner; + void (ObjectType::*callback)(); +}; + +//----------------------------------------------------------------------- +/** + @brief An ByteStream that knows when it's members have changed. + + The AutoDeltaByteStream employs the AutoDeltaVariableBase to + detect changes in it's members. Any AutoDetlaVaraibleBase that + changed since the last packDeltas() method will be placed in the + ByteStream during the next packDeltas() operation. + + ByteStream data is packed as in memory, so + only AutoDeltaByteStreams may interpret a delta package at run time. + + AutoDeltaByteStream objects can also deserialize from ByteStream and + AutoByteStream objects using the unpack() method. To unpack a + delta ByteStream, AutoDeltaByteStream provides unpackDeltas(). + + AutoDeltaVariable objects, which are contained by a + AutoDeltaByteStream, can set threshold values to trigger a + change (e.g. a value representing heading may need to change + by more than 3 degrees before the object is considered "changed"). + + + Example Usage: + \code + class MyAutoDeltaByteStream : public AutoDeltaByteStream + { + public: + MyAutoDeltaByteStream(); + ~MyAutoDeltaByteStream(); + + const float getValue() const; + void setValue(const float value); + + private: + AutoDeltaVariable value; + }; + + MyAutoDeltaByteStream::MyAutoDeltaByteStream() : + value(0.0f) + { + addVariable(value); + value.setDeltaSensitivity(3.0f); + value.clearDelta(); + } + + const float MyAutoDeltaByteStream::getValue() const + { + return value; + } + + void MyAutoDeltaByteStream::setValue(const float newValue) + { + value = newValue; + } + + void foo() + { + MyAutoDeltaByteStream a; + MyAutoDeltaByteStream b; + + a.setValue(2.0f); // change of 2, not enough to trigger a delta + b.setValue(1.0f); + + b.unpackDeltas(a.packDeltas()); + assert(b.getValue() == 1.0f); // no deltas from (a) + + a.setValue(5.0f); // large enough change + b.unpackDeltas(a.packDeltas()); + assert(b.getValue() == a.getValue() && b.getValue() == 5.0f); + } + \endcode + + +*/ +class AutoDeltaByteStream : public AutoByteStream +{ +public: + AutoDeltaByteStream (); + virtual ~AutoDeltaByteStream (); + + void addOnDirtyCallback (OnDirtyCallbackBase * newCallback); + virtual void addVariable (AutoDeltaVariableBase & var); + virtual const unsigned int getItemCount () const; + virtual void packDeltas (ByteStream & target) const; + virtual void unpackDeltas (ReadIterator & source); + virtual void clearDeltas () const; + void removeOnDirtyCallback (); + +protected: + friend class AutoDeltaVariableBase; + void addToDirtyList (AutoDeltaVariableBase * var); + +private: + // disable assignment and copy constructors + AutoDeltaByteStream & operator = (const AutoDeltaByteStream & rhs); + AutoDeltaByteStream (const AutoDeltaByteStream & source); + +private: + mutable std::set dirtyList; // contains AutoVariable's that insert themselves on change + OnDirtyCallbackBase * onDirtyCallback; +}; + +//----------------------------------------------------------------------- +/** + @brief An abstract base class for AutoDeltaVariables + + The AutoDeltaVariableBase defines interfaces for + managing how delta's between packDelta operations + are detected. + + @see AutoDeltaByteStream + @see AutoByteStream + @see ByteStream + @see AutoVariableBase + + @author Justin Randall +*/ +class AutoDeltaVariableBase : public AutoVariableBase +{ +public: + AutoDeltaVariableBase(); + virtual ~AutoDeltaVariableBase() = 0; + + /** pure virtual */ + virtual void clearDelta() const = 0; + + const unsigned short int getIndex() const; + + /** pure virtual */ + virtual const bool isDirty() const = 0; + + void touch(); +protected: + friend class AutoDeltaByteStream; + AutoDeltaByteStream * getOwner(); + void setIndex(const unsigned short int index); + void setOwner(AutoDeltaByteStream * owner); + + /** pure virtual */ + virtual void pack(ByteStream & target) const = 0; + + /** pure virtual */ + virtual void packDelta(ByteStream & target) const = 0; + + /** pure virtual */ + virtual void unpackDelta(ReadIterator & source) = 0; +private: + unsigned short int index; + AutoDeltaByteStream * owner; +}; + +//----------------------------------------------------------------------- +/** + @brief Return the AutoByteStream::members index for this instance. + + A AutoDeltaVariableBase tracks its index in the members list + of the ByteStream. This helper-value permits deserialization of the + value to the appropriate member when the AutoDeltaByteStream invokes + unpackDeltas(). AutoByteStream::packDeltas() prefixes each + delta value with the index of the AutoDeltaVariable. + + + @return the index of the variable in AutoByteStream::members + + @see AutoByteStream + @see AutoDeltaByteStream + @see ByteStream + @see AutoDeltaByteStream::packDeltas + @see AutoDeltaByteStream::unpackDeltas + + @author Justin Randall +*/ +inline const unsigned short int AutoDeltaVariableBase::getIndex() const +{ + return index; +} + +//----------------------------------------------------------------------- +/** + @brief Get a pointer to this variable's owner ByteStream + + As the AutoDeltaVariableBase is used in a non-const + manner, it will insert itself into it's owner AutoDeltaByteStream::dirtyList + set. + + When the AutoDeltaByteStream executes AutoDeltaByteStream::packDeltas(), + it will iterate through this set to determine which + variables may be dirty, invoke AutoDeltaVariableBase::isDirty() on + each variable in the set, and if it is dirty, include the value + in the ByteStream buffer. + + AutoDeltaVariableBase derived classes need to retrieve a + reference to their owner ByteStreams to add them to the + dirtyList set. + + @return a pointer to the owner AutoDeltaByteStream + + @see AutoDeltaByteStream + @see AutoDeltaByteStream::packDeltas + @see AutoDeltaByteStream::unpackDeltas + @see AutoDeltaVariableBase::pack + @see AutoDeltaVariableBase::unpack + + @author Justin Randall +*/ +inline AutoDeltaByteStream * AutoDeltaVariableBase::getOwner() +{ + return owner; +} + +//----------------------------------------------------------------------- +/** + @brief Set the index in the AutoByteStream Members list + + This method is overridden so that the owner value may also + be set. + + @param newIndex An index into the AutoAchive::members list + + @see AutoVariableBase + @see AutoAchive + @see AutoDeltaByteStream + @see ByteStream + + @author Justin Randall +*/ +inline void AutoDeltaVariableBase::setIndex(const unsigned short int newIndex) +{ + index = newIndex; +} + +//----------------------------------------------------------------------- +/** + @brief set the AutoDeltaVariableBase::owner member to the address of + some AutoDeltaByteStream instance. + + A AutoDeltaVariableBase or derived object must put itself on + it's owner AutoDeltaByteStream::dirtyList + +*/ +inline void AutoDeltaVariableBase::setOwner(AutoDeltaByteStream * newOwner) +{ + owner = newOwner; +} + +//----------------------------------------------------------------------- +/** + @brief Put this variable on the owner ByteStream's dirty list + + @author Justin Randall +*/ +inline void AutoDeltaVariableBase::touch() +{ + if(owner) + owner->addToDirtyList(this); +} + +//----------------------------------------------------------------------- +/** + @brief an authoritative variable that knows when it has changed + + A AutoDeltaVariable is use much like a AutoVariable, but it also + knows when it has changed. In addition to knowing when it has changed, + it also may set some change threshold, so that minor variations + in the value can be ignored by the application. + + Example: + \code + class MyAutoDeltaByteStream : public AutoDeltaByteStream + { + public: + MyAutoDeltaByteStream(); + ~MyAutoDeltaByteStream() {}; + + void setValue(const int value) + { i = value; }; + + const int getValue() const + { return i; }; + + private: + AutoDeltaVariable i; + }; + + MyAutoDeltaByteStream::MyAutoDeltaByteStream() + { + addVariable(i); + i.setDeltaSensitivity(5.0f); + }; + + void foo() + { + MyAutoDeltaByteStream a; + MyAutoDeltaByteStream b; + ByteStream c; + + c = a.pack(); // packs all values (just a.i, really) + + b << c; // unpacks all values + assert(a.getValue() == b.getValue()); + + a.setValue(3); + b.unpackDeltas(a.packDeltas()); + assert(a.getValue() != b.getValue()); + + a.setValue(300); + b.unpackDeltas(a.packDeltas()); + assert(a.getValue() == b.getValue()); + } + \endcode + + @see AutoDeltaVariableBase + @see AutoVariable + @see AutoVariableBase + @see AutoDeltaByteStream + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +template +class AutoDeltaVariable : public AutoDeltaVariableBase +{ +public: + AutoDeltaVariable(); + AutoDeltaVariable(const AutoDeltaVariable & source); + explicit AutoDeltaVariable(const ValueType & source); + ~AutoDeltaVariable(); + + AutoDeltaVariable & operator = (const AutoDeltaVariable & source); + AutoDeltaVariable & operator = (const ValueType & source); + + void clearDelta() const; + const ValueType & get() const; + const bool isDirty() const; + void pack(ByteStream & target) const; + void packDelta(ByteStream & target) const; + virtual void set(const ValueType & source); + virtual void unpack(ReadIterator & source); + virtual void unpackDelta(ReadIterator & source); +private: + ValueType currentValue; + mutable ValueType lastValue; +}; + +//----------------------------------------------------------------------- +/** + @brief default AutoDeltaVariable constructor + + @author Justin Randall + + @see AutoVariable + @see AutoVariableBase + @see AutoDeltaVariableBase + @see AutoByteStream + @see ByteStream +*/ +template +inline AutoDeltaVariable::AutoDeltaVariable() : +AutoDeltaVariableBase(), +currentValue(ValueType()), +lastValue(ValueType()) +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoDeltaVariable copy constructor + + This copy constructor will perform a deep copy of the current + value from the source AutoDeltaVariable. It does not copy + AutoDeltaVariableBase members such as the owner. The owner MUST + be set explicitly. + + @author Justin Randall + + @see AutoVariable + @see AutoVariableBase + @see AutoDeltaVariableBase + @see AutoByteStream + @see ByteStream +*/ +template +inline AutoDeltaVariable::AutoDeltaVariable(const AutoDeltaVariable & source) : +AutoDeltaVariableBase(), +currentValue(source.currentValue), +lastValue(source.currentValue) +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoDeltaVariable copy constructor + + A deep copy of the source value is placed in the current value. All + other members use default constructors in the initalizer list. + + \code + MyAutoDeltaByteStream::MyAutoDeltaByteStream() + { + // set myAutoInt current value to 35 + myAutoInt(35); + myAutoInt.setOwner(this); + + // copy myAutoInt + myAutoInt2(myAutoInt); + myAutoInt2.setOwner(this); + + // myAutoInt2 now has a current value of 35 + + } + \endcode + @author Justin Randall + + @see AutoVariable + @see AutoVariableBase + @see AutoDeltaVariableBase + @see AutoByteStream + @see ByteStream +*/ +template +inline AutoDeltaVariable::AutoDeltaVariable(const ValueType & source) : +AutoDeltaVariableBase(), +currentValue(source), +lastValue(source) +{ +} + +//----------------------------------------------------------------------- +/** + @brief AutoDeltaVariable destructor + + Nothing special happens in this desctructor. + + @see AutoDeltaVariableBase + @see AutoByteStream + @see AutoDeltaByteStream + @see ByteStream + + @author Justin Randall +*/ +template +inline AutoDeltaVariable::~AutoDeltaVariable() +{ +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVariable & AutoDeltaVariable::operator =(const AutoDeltaVariable & rhs) +{ + if(&rhs != this) + set(rhs.currentValue); + return *this; +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVariable & AutoDeltaVariable::operator =(const ValueType & rhs) +{ + if(rhs != currentValue) + set(rhs); + return *this; +} + +//----------------------------------------------------------------------- +/** + @brief assign the lastValue to the currentValue to avert isDirty() + returning true. + + @author Justin Randall +*/ +template +inline void AutoDeltaVariable::clearDelta() const +{ + lastValue = currentValue; +} + +//--------------------------------------------------------------------- +/** + @brief return the current value of the AutoDeltaVariable + + @return the current value of the AutoDeltaVariable + + @see AutoDeltaVariableBase + @see AutoVariable + @see AutoDeltaByteStream + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +template +inline const ValueType & AutoDeltaVariable::get() const +{ + return currentValue; +} + +//----------------------------------------------------------------------- +/** + @brief compare last and current values to be sure the value + to determine if the value has changed. + + When a AutoDeltaVariable is used in a non-const manner, it is placed + on the AutoDeltaByteStream::dirtyList until AutoDeltaByteStream::packDeltas() + is invoked. All members on the list are checked to see if their value + has changed enough to warrant a new delta ByteStream. + + Any change in values triggers isDirty() to return true. + + @return true if the variable has changed + + @see AutoDeltaVariable + @see AutoDeltaVariableBase + @see AutoDeltaByteStream + @see AutoVariable + @see AutoVariableBase + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +template +inline const bool AutoDeltaVariable::isDirty() const +{ + return lastValue != currentValue; +} + +//----------------------------------------------------------------------- +/** + @brief pack the ValueType into the target ByteStream + + If the ByteStream understands how to pack the type, or if + a derived class can break the value into it's integral components, + then it is placed into the ByteStream. + + This can be invoked either by an ByteStream base class, or from + AutoDeltaByteStream::packDeltas(). If packing delta values, the + AutoDeltaByteStream first packs an index number into the ByteStream. In + this case, the ByteStream can ONLY be unpacked via another + AutoDeltaByteStream::unpackDeltas(), and the other instance must + declare the same AutoVariableBase types in exactly the same order! + + @param target A target ByteStream object receiving the value + + @see AutoDeltaVariableBase + @see AutoVariableBase + @see AutoDeltaByteStream + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +template +inline void AutoDeltaVariable::pack(ByteStream & target) const +{ + Archive::put(target, currentValue); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariable::packDelta(ByteStream & target) const +{ + pack(target); + clearDelta(); +} + +//--------------------------------------------------------------------- +/** + @brief Set the current value of this AutoDeltaVariable + + @see AutoDeltaVariableBase + @see AutoDeltaByteStream + @see AutoVariable + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +template +inline void AutoDeltaVariable::set(const ValueType & source) +{ + if (currentValue != source) + { + currentValue = source; + touch(); + } +} + +//----------------------------------------------------------------------- +/** + @brief retrieve a value from the source ByteStream + + Read the variable value from the source ByteStream at the current read + position in the ByteStream. To work properly, the ByteStream read position + MUST contain the value -- that is, variables must be retrieve in the + order they were packed. + + AutoByteStream classes and their derivatives automatically pack and + unpack data in the correct order. This protected method is visible + only to ByteStreams. + + @param source The source ByteStream containing the desired value at + its current read position + + @see AutoDeltaVariable + @see AutoDeltaVariableBase + @see AutoDeltaByteStream + @see AutoVariableBase + @see AutoByteStream + @see ByteStream + + @author Justin Randall +*/ +template +inline void AutoDeltaVariable::unpack(ReadIterator & source) +{ + Archive::get(source, currentValue); + clearDelta(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariable::unpackDelta(ReadIterator & source) +{ + Archive::get(source, currentValue); + touch(); +} + +//--------------------------------------------------------------------- + +struct DefaultObjectType {}; + +//----------------------------------------------------------------------- + +static const unsigned char CONTAINER_SET = 0; +static const unsigned char CONTAINER_ERASE = 1; +/** + @brief base container synchronization class + + @author Justin Randall +*/ +class AutoDeltaContainer : public AutoDeltaVariableBase +{ +public: + AutoDeltaContainer(); + /** pure virtual */ + virtual ~AutoDeltaContainer() = 0; + /** pure virtual */ + virtual const size_t size() const = 0; +}; + +//----------------------------------------------------------------------- +/** + @brief ctor + + @author Justin Randall +*/ +inline AutoDeltaContainer::AutoDeltaContainer() : +AutoDeltaVariableBase() +{ +} + +//----------------------------------------------------------------------- +/** + @brief dtor + + @author Justin Randall +*/ +inline AutoDeltaContainer::~AutoDeltaContainer() +{ +} + +//----------------------------------------------------------------------- + +}//namespace Archive + +#endif // _INCLUDED__AutoDeltaByteStream_H diff --git a/external/ours/library/archive/src/shared/AutoDeltaMap.h b/external/ours/library/archive/src/shared/AutoDeltaMap.h new file mode 100644 index 00000000..4f86fc3e --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaMap.h @@ -0,0 +1,754 @@ + +#ifndef _INCLUDED_AutoDeltaMap_H +#define _INCLUDED_AutoDeltaMap_H + +//----------------------------------------------------------------------- + +#include "AutoDeltaByteStream.h" +#include + +//----------------------------------------------------------------------- + +namespace Archive { + +//----------------------------------------------------------------------- +/** + @brief an auto-synchronization map template + + The AutoDeltaMap implements a map container that knows when and what + has changed in the map. The map may be added just like any other + AutoDeltaVariableBase -- invoke addVariable(mapInstance) + + This particular AutoDeltaMap is implemented as a map, though + the interface does not require it to be implemented as such. + + @see AutoDeltaVariableBase + + @author Justin Randall +*/ +template +class AutoDeltaMap : public AutoDeltaContainer +{ +public: + struct Command + { + enum Commands + { + ADD, + ERASE, + SET + }; + unsigned char cmd; + KeyType key; + ValueType value; + }; + +public: // methods + + typedef std::map MapType; + typedef typename MapType::const_iterator const_iterator; + + AutoDeltaMap(); + AutoDeltaMap(const AutoDeltaMap & source); + ~AutoDeltaMap(); + + void clear(); + void clearDelta() const; + const_iterator erase(const KeyType & key); + const_iterator erase(const_iterator & i); + bool empty() const; + const_iterator find(const KeyType & key) const; + const_iterator lower_bound(const KeyType & key) const; + const MapType & getMap() const; + std::pair insert(const KeyType & key, const ValueType & value); + const bool isDirty() const; + void pack(ByteStream & target) const; + void packDelta(ByteStream & target) const; + void set(const KeyType & key, const ValueType & value); + const size_t size() const; + void unpack(ReadIterator & source); + void unpackDelta(ReadIterator & source); + static void pack(ByteStream & target, const std::vector & data); + static void unpack(ReadIterator & source, std::vector & data); + static void unpackDelta(ReadIterator & source, std::vector & data); + + + const_iterator begin() const; + const_iterator end() const; + + void setOnErase (ObjectType * owner, void (ObjectType::*onErase)(const KeyType &, const ValueType &)); + void setOnInsert (ObjectType * owner, void (ObjectType::*onInsert)(const KeyType &, const ValueType &)); + void setOnSet (ObjectType * owner, void (ObjectType::*onSet)(const KeyType &, const ValueType &, const ValueType &)); + +private: + AutoDeltaMap &operator=(const AutoDeltaMap &); + + void onErase(const KeyType &, const ValueType &); + void onInsert(const KeyType &, const ValueType &); + void onSet(const KeyType &, const ValueType &, const ValueType &); + + MapType container; + size_t baselineCommandCount; + mutable std::vector changes; + std::pair *onEraseCallback; + std::pair *onInsertCallback; + std::pair *onSetCallback; +}; + +//----------------------------------------------------------------------- +/** + @brief default constructor, inits base class, container and container + copy + + @author Justin Randall +*/ +template +inline AutoDeltaMap::AutoDeltaMap() : +AutoDeltaContainer(), +container(), +baselineCommandCount(0), +changes(), +onEraseCallback(0), +onInsertCallback(0), +onSetCallback(0) +{ +} + +//----------------------------------------------------------------------- +/** + @brief copy constructor + + @author Justin Randall +*/ +template +inline AutoDeltaMap::AutoDeltaMap(const AutoDeltaMap & source) : +AutoDeltaContainer(), +container(source.container), +baselineCommandCount(0), +changes(), +onEraseCallback(0), +onInsertCallback(0), +onSetCallback(0) +{ +} + +//----------------------------------------------------------------------- +/** + @brief dtor + + @author Justin Randall +*/ +template +inline AutoDeltaMap::~AutoDeltaMap() +{ + delete onEraseCallback; + delete onInsertCallback; + delete onSetCallback; +} + +//----------------------------------------------------------------------- +/** + @brief like std::map::begin(), returns a const_iterator to the first + element in the map. + + Wraps a call to std::map::begin + + @return const_iterator to the first element of the map + + @author Justin Randall +*/ +template +inline typename AutoDeltaMap::const_iterator AutoDeltaMap::begin() const +{ + return container.begin(); +} + +//----------------------------------------------------------------------- +/** + @brief support routine to clear the map. + + @author Steve Jakab +*/ +template +inline void AutoDeltaMap::clear() +{ + //@todo: this is very inefficient! + while (begin() != end()) + { + const_iterator i = begin(); + erase(i); + } +} + + +//----------------------------------------------------------------------- +/** + @brief support routine to clear deltas in the map. + + @author Justin Randall +*/ +template +inline void AutoDeltaMap::clearDelta() const +{ + changes.clear(); +} + +//----------------------------------------------------------------------- +/** + @brief like std::map::end(), returns a const_iterator to the end + of the map. + + @return a const_iterator to the end of the map + + @author Justin Randall +*/ +template +inline typename AutoDeltaMap::const_iterator AutoDeltaMap::end() const +{ + return container.end(); +} + +//----------------------------------------------------------------------- +/** + @brief invokes map::erase(KeyType &) + + Removes an element from the map + + @param key A keyType describing some element of the map + + @author Justin Randall +*/ +template +inline typename AutoDeltaMap::const_iterator AutoDeltaMap::erase(const KeyType & key) +{ + typename std::map::iterator f(container.find(key)); + if (f != container.end()) + { + Command c; + c.cmd = Command::ERASE; + c.key = (*f).first; + c.value = (*f).second; + changes.push_back(c); + ++baselineCommandCount; + container.erase(f++); + touch(); + onErase(key, c.value); + } + return f; +} + +//----------------------------------------------------------------------- +/** + @brief invokes map::erase(const_iterator &) + + Removes and element from the map + + @param i a const_iterator describing an element in the map + + @author Justin Randall +*/ +template +inline typename AutoDeltaMap::const_iterator AutoDeltaMap::erase(const_iterator & i) +{ + return erase((*i).first); +} + +//----------------------------------------------------------------------- +/** + @brief invokes map::empty() + + Returns true if the map is empty. + + @author Acy Stapp +*/ +template +inline bool AutoDeltaMap::empty() const +{ + return container.empty(); +} + +//----------------------------------------------------------------------- +/** + @brief return a map::::const_iterator + + @author Justin Randall +*/ +template +inline typename AutoDeltaMap::const_iterator AutoDeltaMap::find(const KeyType & key) const +{ + return container.find(key); +} + +// ---------------------------------------------------------------------- + +template +inline typename AutoDeltaMap::const_iterator AutoDeltaMap::lower_bound(const KeyType & key) const +{ + return container.lower_bound(key); +} + +//---------------------------------------------------------------------- + +template +inline const typename AutoDeltaMap::MapType & AutoDeltaMap::getMap() const +{ + return container; +} + +//----------------------------------------------------------------------- + +template +#if defined(linux) || _MSC_VER >= 1300 +inline std::pair::const_iterator, bool> AutoDeltaMap::insert(const KeyType & key, const ValueType & value) +#else +inline std::pair::const_iterator, bool> AutoDeltaMap::insert(const KeyType & key, const ValueType & value) +#endif +{ + typedef typename std::map::const_iterator iter; + typedef std::pair insertResult; + + iter i = container.find(key); + if (i != container.end()) + return std::make_pair(i, false); + + Command c; + c.cmd = Command::ADD; + c.key = key; + c.value = value; + insertResult result = container.insert(std::make_pair(key, value)); + touch(); + onInsert(key, value); + changes.push_back(c); + ++baselineCommandCount; + return result; +} + +//----------------------------------------------------------------------- +/** + @brief is the map dirty? + + If any operation has modified the map adds changes to its list, + so if there are any changes, the map is dirty. + + @return true if the map is dirty +*/ +template +inline const bool AutoDeltaMap::isDirty() const +{ + return (!changes.empty()); +} + +//----------------------------------------------------------------------- +/** + @brief pack the whole container + + Iterates through all elements in the container, packing them in + the supplied ByteStream. +*/ +template +inline void AutoDeltaMap::pack(ByteStream & target) const +{ + typename std::map::const_iterator i; + Archive::put(target, container.size()); + Archive::put(target, baselineCommandCount); + unsigned char cmd; + for(i = container.begin(); i != container.end(); ++i) + { + cmd = Command::ADD; + Archive::put(target, cmd); + Archive::put(target, (*i).first); + Archive::put(target, (*i).second); + } +} + +//----------------------------------------------------------------------- +/** + @brief Pack the whole container from a list of updates, without + instantiating the container. + + This converts a vector of commands to a stream of bytes. This + byte stream can be unpacked into an AutoDeltaMap. + + This function is useful when reading the data from a file or database. +*/ +template +inline void AutoDeltaMap::pack(ByteStream & target, const std::vector &data) +{ + Archive::put(target, data.size()); + Archive::put(target, static_cast(0)); // baselineCommandCount + for(typename std::vector::const_iterator c(data.begin()); c != data.end(); ++c) + { + assert(c->cmd == Command::ADD); // only add is valid in packing the whole container + Archive::put(target, c->cmd); + Archive::put(target, c->key); + Archive::put(target, c->value); + } +} + +//----------------------------------------------------------------------- +/** + @brief only pack elements which have changed + + This runs through the list of changes which has already been + generated, and packs them. + + Each add, remove or set are prefixed with a CONTAINER_SET or + CONTAINER_ERASE command. (adds and sets both use CONTAINER_SET). + + @param target a ByteStream object that will receive the delta package + at its current write position + + @author Justin Randall +*/ +template +inline void AutoDeltaMap::packDelta(ByteStream & target) const +{ + Archive::put(target, changes.size()); + Archive::put(target, baselineCommandCount); + for (typename std::vector::iterator i = changes.begin(); i != changes.end(); ++i) + { + const Command & c = (*i); + Archive::put(target, c.cmd); + switch (c.cmd) + { + case Command::ADD: + case Command::SET: + case Command::ERASE: + { + Archive::put(target, c.key); + Archive::put(target, c.value); + } + break; + default: + assert(false); // unknown command put INTO the archive!!!! THis will + // cause a crash when unpacking on a remote system + + } + } + clearDelta(); +} + +//----------------------------------------------------------------------- +/** + @brief get the number of elements in the map + + @return the number of elements in the map +*/ +template +inline const size_t AutoDeltaMap::size() const +{ + return container.size(); +} + +//----------------------------------------------------------------------- +/** + @brief set an element in the map + + If the key does not exist in the map, then an add is queued (which + will trigger a delta), the value is added to the map, and touch() is + called place the container on the AutoDeltaByteStream's dirty list. + + If they key exists, and the values differ, and if the key is not in the + changes set, the old value is stored in changes, the new value is in + the current container's map and the container invokes touch() to + place itself on the AutoDeltaByteStream's dirty list. + + @param key Unique identifier for the value + @param value value associated with the unique key +*/ +template +inline void AutoDeltaMap::set(const KeyType & key, const ValueType & value) +{ + Command c; + typename std::map::iterator i = container.find(key); + if (i == container.end()) + { + c.cmd = Command::ADD; + c.key = key; + c.value = value; + container[key] = value; + touch(); + onInsert(key, value); + changes.push_back(c); + ++baselineCommandCount; + } + else + { + // did it really change? + if ((*i).second != value) + { + c.cmd = Command::SET; + c.key = key; + c.value = value; + ValueType oldValue = i->second; + // set it! + i->second = value; + touch(); + onSet(key, oldValue, value); + changes.push_back(c); + ++baselineCommandCount; + } + } +} + +//----------------------------------------------------------------------- +/** + @brief rebuild the container from a byte stream + + The container first determines the number of changes that will be + applied, which is the first element in the ByteStream. + + Then, for each element, the command is read (CONTAINER_SET or + CONTAINER_ERASE). If it is a CONTAINER_SET, then the key and value + are read from the byte stream and applied to the container. If the + command is CONTAINER_ERASE, the key is retrieved, and the key/value + pair is erased from the container. + + @param source a ByteStream containing the delta or baseline package. +*/ +template +inline void AutoDeltaMap::unpack(ReadIterator & source) +{ + // unpacking baseline data + container.clear(); + clearDelta(); + + Command c; + size_t commandCount; + + Archive::get(source, commandCount); + Archive::get(source, baselineCommandCount); + + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + assert(c.cmd == Command::ADD); // only add is valid in unpack + Archive::get(source, c.key); + Archive::get(source, c.value); + container[c.key] = c.value; + onInsert(c.key, c.value); + } +} + +//----------------------------------------------------------------------- +/** + @brief Get the elements of the container without instantiating it. + + This reads the byte stream like the non-static unpack(), but it constructs + a vector of commands that would build the container. + + This is useful for writing the data to an external data store, e.g. + a file or a database. + + @param source a ByteStream containing the delta or baseline package. +*/ +template +inline void AutoDeltaMap::unpack(ReadIterator & source, std::vector & data) +{ + // unpacking baseline data + + Command c; + size_t commandCount; + size_t baselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, baselineCommandCount); + + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + assert(c.cmd == Command::ADD); // only add is valid in unpack + Archive::get(source, c.key); + Archive::get(source, c.value); + data.push_back(c); + } +} + +//----------------------------------------------------------------------- +/** + @brief update the container from a byte stream +*/ +template +inline void AutoDeltaMap::unpackDelta(ReadIterator & source) +{ + Command c; + size_t skipCount, commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + // if (commandCount+baselineCommandCount) < targetBaselineCommandCount, it + // means that we have missed some changes and are behind; when this happens, + // catch up by applying all the deltas that came in, and set + // baselineCommandCount to targetBaselineCommandCount + if ((commandCount+baselineCommandCount) > targetBaselineCommandCount) + skipCount = commandCount+baselineCommandCount-targetBaselineCommandCount; + else + skipCount = 0; + + // If this fails, it means that the deltas we are receiving are relative to baselines + // which are newer than what we currently have. This usually means either we were not + // observing an object for a time when deltas were sent, but aren't getting new + // baselines, or our version of the container has been modified locally. + if (skipCount > commandCount) + skipCount = commandCount; + + size_t i; + for (i = 0; i < skipCount; ++i) + { + Archive::get(source, c.cmd); + Archive::get(source, c.key); + Archive::get(source, c.value); + } + for ( ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch(c.cmd) + { + case Command::ADD: + case Command::SET: + { + Archive::get(source, c.key); + Archive::get(source, c.value); + AutoDeltaMap::set(c.key, c.value); + } + break; + case Command::ERASE: + { + Archive::get(source, c.key); + Archive::get(source, c.value); + AutoDeltaMap::erase(c.key); + } + break; + default: + assert(false); // unknown command + break; + } + } + + // if we are behind, catch up + if (baselineCommandCount < targetBaselineCommandCount) + baselineCommandCount = targetBaselineCommandCount; +} + +//----------------------------------------------------------------------- +/** + @brief Get the deltas to the container without instantiating it. + + This reads the byte stream like the non-static unpackDeltas(), but it constructs + a vector of commands that would update the container. + + This is useful for writing the data to an external data store, e.g. + a file or a database. + + @param source a ByteStream containing the delta or baseline package. +*/ +template +inline void AutoDeltaMap::unpackDelta(ReadIterator & source, std::vector & data) +{ + Command c; + size_t commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + for (size_t i=0 ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch(c.cmd) + { + case Command::ADD: + case Command::SET: + case Command::ERASE: + { + Archive::get(source, c.key); + Archive::get(source, c.value); + } + break; + default: + assert(false); // unknown command + break; + } + + data.push_back(c); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaMap::onSet(const KeyType &key, const ValueType &oldValue, const ValueType &newValue) +{ + if (onSetCallback && onSetCallback->first) + { + ObjectType &owner = *onSetCallback->first; + void (ObjectType::*cb)(const KeyType &, const ValueType &, const ValueType &) = onSetCallback->second; + (owner.*cb)(key, oldValue, newValue); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaMap::onErase(const KeyType &key, const ValueType &value) +{ + if (onEraseCallback && onEraseCallback->first) + { + ObjectType &owner = *onEraseCallback->first; + void (ObjectType::*cb)(const KeyType &, const ValueType &) = onEraseCallback->second; + (owner.*cb)(key, value); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaMap::onInsert(const KeyType &key, const ValueType &value) +{ + if (onInsertCallback && onInsertCallback->first) + { + ObjectType &owner = *onInsertCallback->first; + void (ObjectType::*cb)(const KeyType &, const ValueType &) = onInsertCallback->second; + (owner.*cb)(key, value); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaMap::setOnErase(ObjectType * owner, void (ObjectType::*cb)(const KeyType &, const ValueType &)) +{ + delete onEraseCallback; + onEraseCallback = new std::pair; + onEraseCallback->first = owner; + onEraseCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaMap::setOnInsert(ObjectType * owner, void (ObjectType::*cb)(const KeyType &, const ValueType &)) +{ + delete onInsertCallback; + onInsertCallback = new std::pair; + onInsertCallback->first = owner; + onInsertCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaMap::setOnSet(ObjectType * owner, void (ObjectType::*cb)(const KeyType &, const ValueType &, const ValueType &)) +{ + delete onSetCallback; + onSetCallback = new std::pair; + onSetCallback->first = owner; + onSetCallback->second = cb; +} + +//----------------------------------------------------------------------- + +}//namespace Archive + +#endif // _INCLUDED__AutoDeltaMap_H + diff --git a/external/ours/library/archive/src/shared/AutoDeltaObserverOps.h b/external/ours/library/archive/src/shared/AutoDeltaObserverOps.h new file mode 100644 index 00000000..e29710fa --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaObserverOps.h @@ -0,0 +1,35 @@ +// ====================================================================== +// +// AutoDeltaObserverOps.h +// Copyright 2001, 2002 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_AutoDeltaObserverOps_H +#define INCLUDED_AutoDeltaObserverOps_H + +//----------------------------------------------------------------------- + +namespace Archive { + +// enum list of every operation that can be performed on an observed object +enum AutoDeltaObserverOp +{ + // base observer ops + ADOO_generic, + ADOO_clear, + ADOO_erase, + ADOO_pop_back, + ADOO_push_back, + ADOO_insert, + ADOO_set, + ADOO_setAll, + ADOO_unpack, + ADOO_unpackDelta, +}; + + +}//namespace Archive + +#endif // INCLUDED_AutoDeltaObserverOps_H diff --git a/external/ours/library/archive/src/shared/AutoDeltaPackedMap.cpp b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.cpp new file mode 100644 index 00000000..64f6684e --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.cpp @@ -0,0 +1,32 @@ +// ====================================================================== +// +// AutoDeltaPackedMap.cpp +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#include "FirstArchive.h" +#include "AutoDeltaPackedMap.h" + +#include + +// ====================================================================== + +namespace Archive +{ + int countCharacter(const std::string &str, char c) + { + int result=0; + for (std::string::const_iterator i=str.begin(); i!=str.end(); ++i) + { + if (*i==c) + ++result; + } + + return result; + } + + +} //namespace + +// ====================================================================== diff --git a/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h new file mode 100644 index 00000000..97ccc1cf --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaPackedMap.h @@ -0,0 +1,240 @@ +// ====================================================================== +// +// AutoDeltaPackedMap.h +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_AutoDeltaPackedMap_H +#define INCLUDED_AutoDeltaPackedMap_H + +// ====================================================================== + +#include +#include "AutoDeltaMap.h" + +// ====================================================================== + +namespace Archive +{ + int countCharacter(const std::string &str, char c); + //These are implemented in sharedFoundation/NetworkIdArchive +#ifdef WIN32 + void get(ReadIterator & source, unsigned __int64 & target); + void put(ByteStream & target, const unsigned __int64 & source); +#else + void get(ReadIterator & source, unsigned long long int & target); + void put(ByteStream & target, const unsigned long long int & source); +#endif + /** + * An AutoDeltaPackedMap is an AutoDeltaMap that will be packed into + * a single value for storage. It functions as an AutoDeltaMap in + * all respects except that packDeltas() will send the entire map + * on the network. + */ + template + class AutoDeltaPackedMap : public AutoDeltaMap + { + public: + AutoDeltaPackedMap(); + AutoDeltaPackedMap(const AutoDeltaPackedMap & source); + ~AutoDeltaPackedMap(); + + static void unpack(ReadIterator & source, std::string & buffer); + static void pack(ByteStream & target, const std::string & buffer); + + virtual void packDelta(ByteStream & target) const; + virtual void unpackDelta(ReadIterator & source); + + void setOnChanged(ObjectType * owner, void (ObjectType::*onChanged)()); + + private: + static void internal_unpack(ReadIterator & source, std::string & buffer, const char * format); + static void internal_pack(ByteStream & target, const std::string & buffer, const char * format); + + void onChanged(); + + std::pair *onChangedCallback; + + private: + AutoDeltaPackedMap & operator=(const AutoDeltaPackedMap &rhs); + }; + + template + inline AutoDeltaPackedMap::AutoDeltaPackedMap() : + AutoDeltaMap(), + onChangedCallback(0) + { + } + + template + inline AutoDeltaPackedMap::AutoDeltaPackedMap(const AutoDeltaPackedMap & source) : + AutoDeltaMap(source), + onChangedCallback(0) + { + } + + template + inline AutoDeltaPackedMap::~AutoDeltaPackedMap() + { + delete onChangedCallback; + } + + template + inline void AutoDeltaPackedMap::packDelta(ByteStream & target) const + { + AutoDeltaMap::pack(target); + } + + template + inline void AutoDeltaPackedMap::unpackDelta(ReadIterator & source) + { + AutoDeltaMap::unpack(source); + onChanged(); + } + + template + inline void AutoDeltaPackedMap::internal_pack(ByteStream & target, const std::string & buffer, const char* format) + { + char temp[200]; + typename AutoDeltaMap::Command c; + + Archive::put(target, countCharacter(buffer,':')); + Archive::put(target, static_cast(0)); // baselineCommandCount + + int tempPos = 0; + for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i) + { + if (*i==':') + { + temp[tempPos]='\0'; + sscanf(temp,format,&c.key, &c.value); + Archive::put(target, static_cast(AutoDeltaMap::Command::ADD)); + Archive::put(target, c.key); + Archive::put(target, c.value); + tempPos=0; + } + else + { + temp[tempPos++]=*i; + } + } + } + + template + inline void AutoDeltaPackedMap::internal_unpack(ReadIterator & source, std::string & buffer, const char *format) + { + char temp[200]; + + typename AutoDeltaMap::Command c; + size_t commandCount; + size_t baselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, baselineCommandCount); + + if (commandCount==0) + { + buffer=' '; // An empty map is represented as a single space, because a completely empty string is used to mean "no change" + } + else + { + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + Archive::get(source, c.key); + Archive::get(source, c.value); + +#ifdef WIN32 + _snprintf(temp, sizeof(temp)-1, format, c.key, c.value); +#else + snprintf(temp, sizeof(temp)-1, format, c.key, c.value); +#endif + + temp[sizeof(temp)-1]='\0'; + buffer+=temp; + } + } + } + + template + inline void AutoDeltaPackedMap::onChanged() + { + if (onChangedCallback && onChangedCallback->first) + { + ObjectType &owner = *onChangedCallback->first; + void (ObjectType::*cb)() = onChangedCallback->second; + (owner.*cb)(); + } + } + + template + inline void AutoDeltaPackedMap::setOnChanged(ObjectType * owner, void (ObjectType::*cb)()) + { + delete onChangedCallback; + onChangedCallback = new std::pair; + onChangedCallback->first = owner; + onChangedCallback->second = cb; + } + + // ====================================================================== + // pack-to-string functions for specific types + + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%i %f"); + } + + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%i %.2f:"); + } + + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%i %i"); + } + + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%i %i:"); + } + + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%i %u"); + } + + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%i %u:"); + } + +#ifdef WIN32 + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%lu %I64u"); + } + + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%lu %I64u:"); + } + +#else + inline void AutoDeltaPackedMap::pack(ByteStream & target, const std::string & buffer) + { + internal_pack(target, buffer, "%lu %llu"); + } + + inline void AutoDeltaPackedMap::unpack(ReadIterator & source, std::string & buffer) + { + internal_unpack(source, buffer, "%lu %llu:"); + } +#endif + +} //namespace + +// ====================================================================== + +#endif diff --git a/external/ours/library/archive/src/shared/AutoDeltaQueue.h b/external/ours/library/archive/src/shared/AutoDeltaQueue.h new file mode 100644 index 00000000..c2f6005f --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaQueue.h @@ -0,0 +1,408 @@ + +#ifndef _INCLUDED_AutoDeltaQueue_H +#define _INCLUDED_AutoDeltaQueue_H + +//----------------------------------------------------------------------- + +#include "AutoDeltaByteStream.h" +#include + +namespace Archive { + +//----------------------------------------------------------------------- + +/** + @brief an auto-synchronization list template + + The AutoDeltaQueue implements a list container that knows when and what + has changed in the list. The list may be added just like any other + AutoDeltaVariableBase -- invoke addVariable(queueInstance) + + This particular AutoDeltaQueue is implemented as a list, though + the interface does not require it to be implemented as such. + + @see AutoDeltaVariableBase +*/ +template +class AutoDeltaQueue: public AutoDeltaContainer +{ +public: // methods + + typedef std::list QueueType; + typedef typename QueueType::iterator iterator; + typedef typename QueueType::const_iterator const_iterator; + + AutoDeltaQueue(); + AutoDeltaQueue(AutoDeltaQueue const &source); + ~AutoDeltaQueue(); + + void clear(); + void clearDelta() const; + iterator find(ValueType const &value); + const_iterator find(ValueType const &value) const; + void erase(iterator i); + void erase(int position); + bool empty() const; + const bool isDirty() const; + void pack(ByteStream &target) const; + void packDelta(ByteStream &target) const; + const size_t size() const; + void unpack(ReadIterator &source); + void unpackDelta(ReadIterator &source); + + void push(ValueType const &value); + void pop(); + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + +private: // members + struct ModifyCommand + { + enum Commands + { + PUSH, + ERASE + }; + unsigned char cmd; + ValueType value; + int position; + }; + + QueueType container; + size_t baselineCommandCount; + mutable std::vector changes; + + AutoDeltaQueue &operator=(AutoDeltaQueue const &); +}; + +//----------------------------------------------------------------------- + +template +inline AutoDeltaQueue::AutoDeltaQueue() : +AutoDeltaContainer(), +container(), +baselineCommandCount(0), +changes() +{ +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaQueue::AutoDeltaQueue(const AutoDeltaQueue &source) : +AutoDeltaContainer(), +container(source.container), +baselineCommandCount(0), +changes() +{ +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaQueue::~AutoDeltaQueue() +{ +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaQueue::iterator AutoDeltaQueue::begin() +{ + return container.begin(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaQueue::const_iterator AutoDeltaQueue::begin() const +{ + return container.begin(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::clear() +{ + //@todo: this is very inefficient! + while (begin() != end()) + { + erase(begin()); + } +} + + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::clearDelta() const +{ + changes.clear(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaQueue::iterator AutoDeltaQueue::end() +{ + return container.end(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaQueue::const_iterator AutoDeltaQueue::end() const +{ + return container.end(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::erase(iterator i) +{ + if (i != container.end()) + { + ModifyCommand c; + c.cmd = ModifyCommand::ERASE; + c.position = std::distance(container.begin(), i); + changes.push_back(c); + ++baselineCommandCount; + container.erase(i); + touch(); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::erase(int position) +{ + if (position < static_cast(size())) + { + ModifyCommand c; + c.cmd = ModifyCommand::ERASE; + c.position = position; + changes.push_back(c); + ++baselineCommandCount; + iterator i = begin(); + std::advance(i, position); + container.erase(i); + touch(); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::pop() +{ + if (!empty()) + { + ModifyCommand c; + c.cmd = ModifyCommand::ERASE; + c.position = 0; + changes.push_back(c); + ++baselineCommandCount; + container.pop_front(); + touch(); + } +} + +//----------------------------------------------------------------------- + +template +inline bool AutoDeltaQueue::empty() const +{ + return container.empty(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaQueue::iterator AutoDeltaQueue::find(ValueType const &value) +{ + return container.find(value); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaQueue::const_iterator AutoDeltaQueue::find(ValueType const &value) const +{ + return container.find(value); +} + +//---------------------------------------------------------------------- + +template +inline const bool AutoDeltaQueue::isDirty() const +{ + return (!changes.empty()); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::pack(ByteStream &target) const +{ + const_iterator i; + Archive::put(target, container.size()); + Archive::put(target, baselineCommandCount); + unsigned char cmd; + for (i = container.begin(); i != container.end(); ++i) + { + cmd = ModifyCommand::PUSH; + Archive::put(target, cmd); + Archive::put(target, (*i)); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::packDelta(ByteStream &target) const +{ + Archive::put(target, changes.size()); + Archive::put(target, baselineCommandCount); + for (typename std::vector::iterator i = changes.begin(); i != changes.end(); ++i) + { + const ModifyCommand &c = (*i); + Archive::put(target, c.cmd); + switch(c.cmd) + { + case ModifyCommand::PUSH: + { + Archive::put(target, c.value); + } + break; + case ModifyCommand::ERASE: + { + Archive::put(target, c.position); + } + break; + } + } + clearDelta(); +} + +//----------------------------------------------------------------------- + +template +inline const size_t AutoDeltaQueue::size() const +{ + return container.size(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::push(ValueType const &value) +{ + ModifyCommand c; + c.cmd = ModifyCommand::PUSH; + c.value = value; + container.push_back(value); + touch(); + changes.push_back(c); + ++baselineCommandCount; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::unpack(ReadIterator &source) +{ + // unpacking baseline data + container.clear(); + clearDelta(); + + ModifyCommand c; + size_t commandCount; + + Archive::get(source, commandCount); + Archive::get(source, baselineCommandCount); + + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + assert(c.cmd == ModifyCommand::PUSH); // only push valid for pack/unpack + Archive::get(source, c.value); + container.push_back(c.value); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaQueue::unpackDelta(ReadIterator &source) +{ + ModifyCommand c; + size_t skipCount, commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + skipCount = commandCount+baselineCommandCount-targetBaselineCommandCount; + + // If this fails, it means that the deltas we are receiving are relative to baselines + // which are newer than what we currently have. This usually means either we were not + // observing an object for a time when deltas were sent, but aren't getting new + // baselines, or our version of the container has been modified locally. + if (skipCount > commandCount) + skipCount = commandCount; + + size_t i; + for (i = 0; i < skipCount; ++i) + { + Archive::get(source, c.cmd); + switch (c.cmd) + { + case ModifyCommand::PUSH: + { + Archive::get(source, c.value); + } + break; + case ModifyCommand::ERASE: + { + Archive::get(source, c.position); + } + break; + default: + assert(false); + break; + } + } + for ( ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch (c.cmd) + { + case ModifyCommand::PUSH: + { + Archive::get(source, c.value); + AutoDeltaQueue::push(c.value); + } + break; + case ModifyCommand::ERASE: + { + Archive::get(source, c.position); + AutoDeltaQueue::erase(c.position); + } + break; + default: + assert(false); // unknown command + break; + } + } +} + +//----------------------------------------------------------------------- + +} //namespace Archive + +#endif // _INCLUDED__AutoDeltaQueue_H diff --git a/external/ours/library/archive/src/shared/AutoDeltaSet.h b/external/ours/library/archive/src/shared/AutoDeltaSet.h new file mode 100644 index 00000000..af61b672 --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaSet.h @@ -0,0 +1,537 @@ +// ====================================================================== +// +// AutoDeltaSet.h +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef _INCLUDED_AutoDeltaSet_H +#define _INCLUDED_AutoDeltaSet_H + +// ====================================================================== + +#include "AutoDeltaByteStream.h" + +// ====================================================================== + +namespace Archive { + +//----------------------------------------------------------------------- + +template +class AutoDeltaSet: public AutoDeltaContainer +{ + +public: + typedef std::set SetType; + typedef typename SetType::size_type size_type; + typedef typename SetType::const_iterator const_iterator; + typedef typename SetType::const_reverse_iterator const_reverse_iterator; + +public: + struct Command + { + enum + { + ERASE, + INSERT, + CLEAR + }; + unsigned char cmd; + ValueType value; + }; + +public: + AutoDeltaSet(); + ~AutoDeltaSet(); + + const_iterator begin() const; + const_iterator end() const; + const_reverse_iterator rbegin() const; + const_reverse_iterator rend() const; + + void clearDelta() const; + const bool isDirty() const; + void pack(ByteStream &target) const; + void packDelta(ByteStream &target) const; + + SetType const & get() const; + const size_t size() const; + bool empty() const; + bool contains(ValueType const &t) const; + const_iterator find(ValueType const &t) const; + + virtual void clear(); + virtual const_iterator erase(ValueType const &t); + virtual const_iterator erase(const_iterator &i); + virtual void insert(ValueType const &t); + virtual void unpack(ReadIterator &source); + virtual void unpackDelta(ReadIterator &source); + + static void pack(ByteStream &target, std::set const &data); + static void unpack(ReadIterator &source, std::vector &data); + static void unpackDelta(ReadIterator &source, std::vector &data); + + void setOnChanged(ObjectType *owner, void (ObjectType::*onChanged)()); + void setOnErase(ObjectType *owner, void (ObjectType::*onErase)(ValueType const &)); + void setOnInsert(ObjectType *owner, void (ObjectType::*onInsert)(ValueType const &)); + +private: + void onChanged(); + void onErase(const ValueType &); + void onInsert(const ValueType &); + +private: + SetType m_set; + size_t m_baselineCommandCount; + mutable std::vector m_commands; + std::pair *m_onChangedCallback; + std::pair *m_onEraseCallback; + std::pair *m_onInsertCallback; + +private: + AutoDeltaSet(AutoDeltaSet const &); +}; + +//----------------------------------------------------------------------- + +template +inline AutoDeltaSet::AutoDeltaSet() : + AutoDeltaContainer(), + m_set(), + m_baselineCommandCount(0), + m_commands(), + m_onChangedCallback(0), + m_onEraseCallback(0), + m_onInsertCallback(0) +{ +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaSet::~AutoDeltaSet() +{ + delete m_onChangedCallback; + delete m_onEraseCallback; + delete m_onInsertCallback; +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_iterator AutoDeltaSet::begin() const +{ + return m_set.begin(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::clear() +{ + if (!empty()) + { + Command c; + c.cmd = Command::CLEAR; + m_commands.push_back(c); + ++m_baselineCommandCount; + for (typename SetType::iterator i = m_set.begin(); i != m_set.end(); ++i) + onErase(*i); + m_set.clear(); + touch(); + onChanged(); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::clearDelta() const +{ + m_commands.clear(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_iterator AutoDeltaSet::end() const +{ + return m_set.end(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_iterator AutoDeltaSet::erase(ValueType const &value) +{ + typename SetType::const_iterator i(find(value)); + + return erase(i); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_iterator AutoDeltaSet::erase(const_iterator &i) +{ + if (i != m_set.end()) + { + Command c; + c.cmd = Command::ERASE; + c.value = *i; + m_commands.push_back(c); + ++m_baselineCommandCount; + m_set.erase(i++); + touch(); + onErase(c.value); + onChanged(); + } + + return i; +} + +//----------------------------------------------------------------------- + +template +inline bool AutoDeltaSet::contains(ValueType const &value) const +{ + return m_set.find(value) != m_set.end(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_iterator AutoDeltaSet::find(ValueType const &value) const +{ + return m_set.find(value); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::SetType const &AutoDeltaSet::get() const +{ + return m_set; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::insert(ValueType const &value) +{ + if (m_set.insert(value).second) + { + Command c; + c.cmd = Command::INSERT; + c.value = value; + m_commands.push_back(c); + ++m_baselineCommandCount; + touch(); + onInsert(value); + onChanged(); + } +} + +//----------------------------------------------------------------------- + +template +inline const bool AutoDeltaSet::isDirty() const +{ + return m_commands.size() > 0; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::onChanged() +{ + if (m_onChangedCallback) + { + if (m_onChangedCallback->first) + { + ObjectType &owner = *m_onChangedCallback->first; + void (ObjectType::*cb)() = m_onChangedCallback->second; + (owner.*cb)(); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::onErase(ValueType const &value) +{ + if (m_onEraseCallback) + { + if (m_onEraseCallback->first) + { + ObjectType &owner = *m_onEraseCallback->first; + void (ObjectType::*cb)(ValueType const &) = m_onEraseCallback->second; + (owner.*cb)(value); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::onInsert(ValueType const &value) +{ + if (m_onInsertCallback) + { + if (m_onInsertCallback->first) + { + ObjectType &owner = *m_onInsertCallback->first; + void (ObjectType::*cb)(ValueType const &) = m_onInsertCallback->second; + (owner.*cb)(value); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::pack(ByteStream &target) const +{ + Archive::put(target, m_set.size()); + Archive::put(target, m_baselineCommandCount); + for (typename SetType::const_iterator i = m_set.begin(); i != m_set.end(); ++i) + Archive::put(target, *i); +} + +// ---------------------------------------------------------------------- + +template +inline void AutoDeltaSet::pack(ByteStream &target, std::set const &data) +{ + Archive::put(target, data.size()); + Archive::put(target, static_cast(0)); // baselineCommandCount + for (typename std::set::const_iterator i = data.begin(); i != data.end(); ++i) + Archive::put(target, *i); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::packDelta(ByteStream &target) const +{ + Archive::put(target, m_commands.size()); + Archive::put(target, m_baselineCommandCount); + for (typename std::vector::iterator i = m_commands.begin(); i != m_commands.end(); ++i) + { + Command const &c = *i; + Archive::put(target, c.cmd); + switch (c.cmd) + { + case Command::ERASE: + case Command::INSERT: + Archive::put(target, c.value); + break; + case Command::CLEAR: + break; + } + } + clearDelta(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_reverse_iterator AutoDeltaSet::rbegin() const +{ + return m_set.rbegin(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSet::const_reverse_iterator AutoDeltaSet::rend() const +{ + return m_set.rend(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::setOnChanged(ObjectType *owner, void (ObjectType::*cb)()) +{ + delete m_onChangedCallback; + m_onChangedCallback = new std::pair; + m_onChangedCallback->first = owner; + m_onChangedCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::setOnErase(ObjectType *owner, void (ObjectType::*cb)(ValueType const &)) +{ + delete m_onEraseCallback; + m_onEraseCallback = new std::pair; + m_onEraseCallback->first = owner; + m_onEraseCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::setOnInsert(ObjectType *owner, void (ObjectType::*cb)(ValueType const &)) +{ + delete m_onInsertCallback; + m_onInsertCallback = new std::pair; + m_onInsertCallback->first = owner; + m_onInsertCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline bool AutoDeltaSet::empty() const +{ + return m_set.empty(); +} + +//----------------------------------------------------------------------- + +template +inline const size_t AutoDeltaSet::size() const +{ + return m_set.size(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::unpack(ReadIterator &source) +{ + m_set.clear(); + clearDelta(); + + size_t commandCount; + ValueType value; + + Archive::get(source, commandCount); + Archive::get(source, m_baselineCommandCount); + + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source, value); + m_set.insert(value); + } + + onChanged(); +} + +// ---------------------------------------------------------------------- + +template +inline void AutoDeltaSet::unpack(ReadIterator &source, std::vector &data) +{ + Command c; + size_t commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + c.cmd = Command::INSERT; + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source,c.value); + data.push_back(c); + } +} + +// ---------------------------------------------------------------------- + +template +inline void AutoDeltaSet::unpackDelta(ReadIterator &source, std::vector &data) +{ + Command c; + size_t commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + for (size_t i = 0 ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch (c.cmd) + { + case Command::ERASE: + case Command::INSERT: + Archive::get(source, c.value); + break; + case Command::CLEAR: + break; + default: + assert(false); + break; + } + data.push_back(c); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSet::unpackDelta(ReadIterator &source) +{ + Command c; + size_t skipCount, commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + // if (commandCount+baselineCommandCount) < targetBaselineCommandCount, it + // means that we have missed some changes and are behind; when this happens, + // catch up by applying all the deltas that came in, and set + // baselineCommandCount to targetBaselineCommandCount + if ((commandCount+m_baselineCommandCount) > targetBaselineCommandCount) + skipCount = commandCount+m_baselineCommandCount-targetBaselineCommandCount; + else + skipCount = 0; + + if (skipCount > commandCount) + skipCount = commandCount; + + size_t i = 0; + for ( ; i < skipCount; ++i) + { + Archive::get(source, c.cmd); + if (c.cmd != Command::CLEAR) + Archive::get(source, c.value); + } + for ( ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch (c.cmd) + { + case Command::ERASE: + Archive::get(source, c.value); + AutoDeltaSet::erase(c.value); + break; + case Command::INSERT: + Archive::get(source, c.value); + AutoDeltaSet::insert(c.value); + break; + case Command::CLEAR: + AutoDeltaSet::clear(); + break; + } + } + + // if we are behind, catch up + if (m_baselineCommandCount < targetBaselineCommandCount) + m_baselineCommandCount = targetBaselineCommandCount; +} + +//--------------------------------------------------------------------- + +}//namespace Archive + +// ====================================================================== + +#endif // _INCLUDED__AutoDeltaSet_H + diff --git a/external/ours/library/archive/src/shared/AutoDeltaSetObserver.h b/external/ours/library/archive/src/shared/AutoDeltaSetObserver.h new file mode 100644 index 00000000..42aff40f --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaSetObserver.h @@ -0,0 +1,135 @@ +// ====================================================================== +// +// AutoDeltaSetObserver.h +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef _INCLUDED_AutoDeltaSetObserver_H +#define _INCLUDED_AutoDeltaSetObserver_H + +// ====================================================================== + +#include "AutoDeltaSet.h" +#include "AutoDeltaObserverOps.h" + +// ---------------------------------------------------------------------- + +namespace Archive { + +// ---------------------------------------------------------------------- + +template +class AutoDeltaSetObserver: public AutoDeltaSet +{ +public: + typedef std::set SetType; + typedef typename SetType::const_iterator const_iterator; + + AutoDeltaSetObserver(); + ~AutoDeltaSetObserver(); + + void setSourceObject(SourceObjectType *source); + + virtual void clear (); + virtual typename SetType::const_iterator erase(ValueType const &value); + virtual typename SetType::const_iterator erase(const_iterator & i); + virtual void insert (ValueType const &value); + virtual void unpack (ReadIterator &source); + virtual void unpackDelta (ReadIterator &source); + +private: + AutoDeltaSetObserver(AutoDeltaSetObserver const &); + AutoDeltaSetObserver &operator=(AutoDeltaSetObserver const &); + +private: + SourceObjectType *sourceObject; +}; + +//---------------------------------------------------------------- + +template +inline AutoDeltaSetObserver::AutoDeltaSetObserver() : + AutoDeltaSet(), + sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaSetObserver::~AutoDeltaSetObserver() +{ +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSetObserver::setSourceObject(SourceObjectType *source) +{ + sourceObject = source; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSetObserver::clear() +{ + Callback callback(sourceObject, ADOO_clear); + AutoDeltaSet::clear(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSetObserver::const_iterator AutoDeltaSetObserver::erase(ValueType const &value) +{ + Callback callback(sourceObject, ADOO_erase); + return AutoDeltaSet::erase(value); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaSetObserver::const_iterator AutoDeltaSetObserver::erase(const_iterator & i) +{ + Callback callback(sourceObject, ADOO_erase); + return AutoDeltaSet::erase(i); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSetObserver::insert(ValueType const &value) +{ + Callback callback(sourceObject, ADOO_insert); + AutoDeltaSet::insert(value); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSetObserver::unpack(ReadIterator &source) +{ + Callback callback(sourceObject, ADOO_unpack); + AutoDeltaSet::unpack(source); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaSetObserver::unpackDelta(ReadIterator &source) +{ + Callback callback(sourceObject, ADOO_unpackDelta); + AutoDeltaSet::unpackDelta(source); +} + +//----------------------------------------------------------------------- + +} + +// ====================================================================== + +#endif + diff --git a/external/ours/library/archive/src/shared/AutoDeltaVariableCallback.h b/external/ours/library/archive/src/shared/AutoDeltaVariableCallback.h new file mode 100644 index 00000000..ef0cc7fa --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaVariableCallback.h @@ -0,0 +1,240 @@ +#ifndef _INCLUDED_AutoDeltaVariableCallback_H +#define _INCLUDED_AutoDeltaVariableCallback_H + + +#include "AutoDeltaByteStream.h" + +namespace Archive { + +/** + @brief an authoritative variable that provides notification when changed + + An AutoDeltaVariableCallback is an AutoDeltaVariable. It extends the functionality + of AutoDeltaVariable by providing an interface for getting callbacks when the value changes. + + To use the AutoDeltaVariableCallback, you must pass it a callback structure. An example is provided here: + + struct ExampleDataCallback + { + void modified(TangibleObject & target, const std::string & value) const; + }; + + This simple structure defines only one function, which will be invoked by the AutoDeltaVariableCallback + when the variable is changed by a set(), operator=, or unpack() method. + + Then to declare an AutoDeltaVariableCallback as a member of an example class you might: + + class MyExampleClass + { + private: + struct ExampleDataCallback + { + //define modified to call MyExampleClass::dataModified(value) + void modified(MyExampleClass & target, ValueType & value) const {target.dataModified(value);} + }; + + //Friend it so that outsiders don't screw with the callback function but so that it can use it. + friend struct ExampleDataCallback; + void dataModified(ValueType & value); + + Archive::AutoDeltaVariableCallback m_data; + }; + + In the constructor of MyExampleClass: + m_data->setSourceObject(this); //This registers the correct instance of the object with the variable + addVariable(m_data); //See AutoDeltaVariable for why this is done. + + @see AutoDeltaVariable + @see AutoDeltaVariableBase + + @author Chris Mayer +*/ + +template +class AutoDeltaVariableCallback : public AutoDeltaVariable +{ +public: + + AutoDeltaVariableCallback(); + AutoDeltaVariableCallback(const AutoDeltaVariableCallback & source); + explicit AutoDeltaVariableCallback(const ValueType & source); + ~AutoDeltaVariableCallback(); + + AutoDeltaVariableCallback & operator = (const AutoDeltaVariableCallback & source); + AutoDeltaVariableCallback & operator = (const ValueType & source); + + virtual void set(const ValueType & source); + void setSourceObject(SourceObjectType * source); + + virtual void unpack(ReadIterator & source); + virtual void unpackDelta(ReadIterator & source); + +private: + Callback callback; + SourceObjectType* sourceObject; +}; + +//---------------------------------------------------------------- +/** + @brief default AutoDeltaVariableCallback constructor + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline AutoDeltaVariableCallback::AutoDeltaVariableCallback() : +AutoDeltaVariable(), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- +/** + @brief default AutoDeltaVariableCallback copy constructor + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline AutoDeltaVariableCallback::AutoDeltaVariableCallback(const AutoDeltaVariableCallback & source) : +AutoDeltaVariable(source), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +/** + @brief default AutoDeltaVariableCallback constructor given value + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline AutoDeltaVariableCallback::AutoDeltaVariableCallback(const ValueType & source) : +AutoDeltaVariable(source), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- +/** + @brief default AutoDeltaVariableCallback destructor + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline AutoDeltaVariableCallback::~AutoDeltaVariableCallback() +{ +} +//---------------------------------------------------------------- + +template +inline AutoDeltaVariableCallback & AutoDeltaVariableCallback::operator =(const AutoDeltaVariableCallback & rhs) +{ + if (&rhs != this) + set(rhs.get()); + return *this; +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVariableCallback & AutoDeltaVariableCallback::operator = (const ValueType & rhs) +{ + if (rhs != this->get()) + set(rhs); + return *this; +} + +//----------------------------------------------------------------------- +/** + @brief setSourceObject registers the object that owns the variable so that we can provide callback notification. + + This function should be called in the owning classes constructor before it is used. + Failure to call this function before the variable's first use will cause an assertion failure. + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline void AutoDeltaVariableCallback::setSourceObject(SourceObjectType * source) +{ + sourceObject = source; +} + +//----------------------------------------------------------------------- + +/** + @brief overload AutoDeltaVariable::set to provide for callback notification + + ::set() will notifiy the callback object after setting the value by calling the base class ::set() function. + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline void AutoDeltaVariableCallback::set(const ValueType & source) +{ + ValueType const tmp = this->get(); + AutoDeltaVariable::set(source); + + if (sourceObject != NULL && tmp != source) + callback.modified(*sourceObject, tmp, source, true); +} + +//----------------------------------------------------------------------- +/** + @brief overload AutoDeltaVariable::unpack to provide for callback notification + + ::unpack() will notifiy the callback object after setting the value by calling the base class ::unpack() function. + + @author Chris Mayer + + @see AutoDeltaVariable +*/ +template +inline void AutoDeltaVariableCallback::unpack(ReadIterator & source) +{ + ValueType const before = this->get(); + + AutoDeltaVariable::unpack(source); + + if (sourceObject) + { + ValueType const &after = this->get(); + if (before != after) + callback.modified(*sourceObject, before, after, false); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariableCallback::unpackDelta(ReadIterator & source) +{ + ValueType const before = this->get(); + + AutoDeltaVariable::unpackDelta(source); + + if (sourceObject) + { + ValueType const &after = this->get(); + if (before != after) + callback.modified(*sourceObject, before, after, false); + } +} + +//----------------------------------------------------------------------- + +} + +#endif + diff --git a/external/ours/library/archive/src/shared/AutoDeltaVariableObserver.h b/external/ours/library/archive/src/shared/AutoDeltaVariableObserver.h new file mode 100644 index 00000000..86a2434d --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaVariableObserver.h @@ -0,0 +1,131 @@ +#ifndef _INCLUDED_AutoDeltaVariableObserver_H +#define _INCLUDED_AutoDeltaVariableObserver_H + + +#include "AutoDeltaByteStream.h" +#include "AutoDeltaObserverOps.h" + +namespace Archive { + +/** + @brief an authoritative variable that provides notification both prior to and after change +*/ + +template +class AutoDeltaVariableObserver : public AutoDeltaVariable +{ +public: + + AutoDeltaVariableObserver(); + AutoDeltaVariableObserver(const AutoDeltaVariableObserver & source); + explicit AutoDeltaVariableObserver(const ValueType & source); + ~AutoDeltaVariableObserver(); + + AutoDeltaVariableObserver & operator = (const AutoDeltaVariableObserver & source); + AutoDeltaVariableObserver & operator = (const ValueType & source); + + virtual void set(const ValueType & source); + void setSourceObject(SourceObjectType * source); + + virtual void unpack(ReadIterator & source); + virtual void unpackDelta(ReadIterator & source); + +private: + SourceObjectType* sourceObject; +}; + +//---------------------------------------------------------------- + +template +inline AutoDeltaVariableObserver::AutoDeltaVariableObserver() : +AutoDeltaVariable(), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVariableObserver::AutoDeltaVariableObserver(const AutoDeltaVariableObserver & source) : +AutoDeltaVariable(source), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVariableObserver::AutoDeltaVariableObserver(const ValueType & source) : +AutoDeltaVariable(source), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVariableObserver::~AutoDeltaVariableObserver() +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVariableObserver & AutoDeltaVariableObserver::operator =(const AutoDeltaVariableObserver & rhs) +{ + if (&rhs != this) + set(rhs.get()); + return *this; +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVariableObserver & AutoDeltaVariableObserver::operator = (const ValueType & rhs) +{ + if (rhs != this->get()) + set(rhs); + return *this; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariableObserver::setSourceObject(SourceObjectType * source) +{ + sourceObject = source; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariableObserver::set(const ValueType & source) +{ + Callback callback(sourceObject, ADOO_set); + AutoDeltaVariable::set(source); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariableObserver::unpack(ReadIterator & source) +{ + Callback callback(sourceObject, ADOO_unpack); + AutoDeltaVariable::unpack(source); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVariableObserver::unpackDelta(ReadIterator & source) +{ + Callback callback(sourceObject, ADOO_unpackDelta); + AutoDeltaVariable::unpackDelta(source); +} + +//----------------------------------------------------------------------- + +} + +#endif + diff --git a/external/ours/library/archive/src/shared/AutoDeltaVector.h b/external/ours/library/archive/src/shared/AutoDeltaVector.h new file mode 100644 index 00000000..0f0b4e03 --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaVector.h @@ -0,0 +1,796 @@ + +#ifndef _INCLUDED_AutoDeltaVector_H +#define _INCLUDED_AutoDeltaVector_H + +//----------------------------------------------------------------------- + +#include "AutoDeltaByteStream.h" + +//----------------------------------------------------------------------- + +namespace Archive { + +//----------------------------------------------------------------------- + +template +class AutoDeltaVector : public AutoDeltaContainer +{ + typedef typename std::vector::size_type size_type; + +public: + typedef typename std::vector::const_iterator const_iterator; + typedef typename std::vector::const_reverse_iterator const_reverse_iterator; + typedef std::vector VectorType; + +public: + struct Command + { + enum + { + ERASE, + INSERT, + SET, + SETALL, + CLEAR + }; + unsigned char cmd; + unsigned short int index; + ValueType value; + }; + +public: + AutoDeltaVector(); + explicit AutoDeltaVector(size_t initialSize); + ~AutoDeltaVector(); + + const ValueType & back () const; + const_iterator begin () const; + void clearDelta () const; + const_iterator end () const; + const int find (const ValueType & t) const; + const ValueType & front () const; + const VectorType & get () const; + const ValueType & get (const unsigned int element) const; + const bool isDirty () const; + void pack (ByteStream & target) const; + void packDelta (ByteStream & target) const; + void reserve (size_type n); + void resize (size_type n, ValueType x = ValueType()); + + virtual void clear (); + virtual void erase (const unsigned int element); + virtual void pop_back (); + virtual void push_back (const ValueType & t); + virtual void insert (const unsigned int before, const ValueType & newValue); + virtual void set (const unsigned int element, const ValueType & newValue); + virtual void set (const VectorType & newValue); + virtual void unpack (ReadIterator & source); + virtual void unpackDelta (ReadIterator & source); + static void pack (ByteStream & target, const std::vector & data); + static void unpack (ReadIterator & source, std::vector & data); + static void unpackDelta (ReadIterator & source, std::vector & data); + + void setOnChanged (ObjectType * owner, void (ObjectType::*onChanged)()); + void setOnErase (ObjectType * owner, void (ObjectType::*onErase)(const unsigned int, const ValueType &)); + void setOnInsert (ObjectType * owner, void (ObjectType::*onInsert)(const unsigned int, const ValueType &)); + void setOnSet (ObjectType * owner, void (ObjectType::*onSet)(const unsigned int, const ValueType &, const ValueType &)); + + const size_t size () const; + bool empty () const; + + const ValueType & operator[] (const unsigned int element) const; + + const_reverse_iterator rbegin() const; + const_reverse_iterator rend() const; + +private: + void packCommand(const Command & command, ByteStream & target) const; + void onChanged(); + void onErase(const unsigned int, const ValueType &); + void onInsert(const unsigned int, const ValueType &); + void onSet(const unsigned int, const ValueType &, const ValueType &); + +private: + std::vector v; + size_t baselineCommandCount; + mutable std::vector commands; + std::pair * onChangedCallback; + std::pair * onEraseCallback; + std::pair * onInsertCallback; + std::pair * onSetCallback; + +private: + AutoDeltaVector(const AutoDeltaVector &); +}; + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVector::AutoDeltaVector() : +AutoDeltaContainer(), +v(), +baselineCommandCount(0), +commands(), +onChangedCallback(0), +onEraseCallback(0), +onInsertCallback(0), +onSetCallback(0) +{ +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVector::AutoDeltaVector(size_t initialSize) : +AutoDeltaContainer(), +v(initialSize), +baselineCommandCount(0), +commands(), +onChangedCallback(0), +onEraseCallback(0), +onInsertCallback(0), +onSetCallback(0) +{ +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVector::~AutoDeltaVector() +{ + delete onChangedCallback; + delete onEraseCallback; + delete onInsertCallback; + delete onSetCallback; +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaVector::const_iterator AutoDeltaVector::begin() const +{ + return v.begin(); +} + +//----------------------------------------------------------------------- + +/** +* @todo this is very inefficient +*/ +template +inline void AutoDeltaVector::clear() +{ + if (!empty()) + { + Command c; + c.cmd = Command::CLEAR; + commands.push_back(c); + ++baselineCommandCount; + for (unsigned int i = 0; i < v.size(); ++i) + onErase(i, v[i]); + v.clear(); + touch(); + onChanged(); + } +} + +//----------------------------------------------------------------------- + +template +inline const ValueType & AutoDeltaVector::back() const +{ + return v.back(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::clearDelta() const +{ + commands.clear(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaVector::const_iterator AutoDeltaVector::end() const +{ + return v.end(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::erase(const unsigned int element) +{ + if(element < size()) + { + Command c; + c.cmd = Command::ERASE; + + //-- cast to shorts to reduce net traffic. If we are synchronizing + // vectors with more than 65,535 elements, we have some serious + // design issues + c.index = static_cast(element); + //-- + + commands.push_back(c); + ++baselineCommandCount; + typename std::vector::iterator i = v.begin(); + std::advance(i, element); + ValueType old = (*i); + v.erase(i); + touch(); + onErase(element, old); + onChanged(); + } +} +//----------------------------------------------------------------------- +template +inline const int AutoDeltaVector::find(const ValueType & item) const +{ + int count = 0; + for (typename std::vector::const_iterator i = v.begin(); i != v.end(); ++i) + { + if (item == (*i)) + { + return count; + } + ++count; + } + return -1; +} + +//----------------------------------------------------------------------- + +template +inline const ValueType & AutoDeltaVector::front() const +{ + assert (!v.empty ()); + return v.front(); +} + +//----------------------------------------------------------------------- + +template +inline const ValueType & AutoDeltaVector::get(const unsigned int element) const +{ + assert (v.size () > element); + return v[element]; +} + +//---------------------------------------------------------------------- + +template +inline const typename AutoDeltaVector::VectorType & AutoDeltaVector::get() const +{ + return v; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::insert(const unsigned int before, const ValueType & newValue) +{ + Command c; + c.cmd = Command::INSERT; + c.index = static_cast(before); + c.value = newValue; + commands.push_back(c); + ++baselineCommandCount; + + if (v.size() < before) + v.resize(before); + + typename std::vector::iterator i = v.begin(); + std::advance(i, before); + v.insert(i, newValue); + touch(); + onInsert(before, newValue); + onChanged(); +} + +//----------------------------------------------------------------------- + +template +inline const bool AutoDeltaVector::isDirty() const +{ + return commands.size() > 0; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::onChanged() +{ + if(onChangedCallback) + { + if(onChangedCallback->first) + { + ObjectType & owner = *onChangedCallback->first; + void (ObjectType::*cb)() = onChangedCallback->second; + (owner.*cb)(); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::onErase(const unsigned int element, const ValueType & oldValue) +{ + if(onEraseCallback) + { + if(onEraseCallback->first) + { + ObjectType & owner = *onEraseCallback->first; + void (ObjectType::*cb)(const unsigned int, const ValueType &) = onEraseCallback->second; + (owner.*cb)(element, oldValue); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::onInsert(const unsigned int element, const ValueType & newValue) +{ + if(onInsertCallback) + { + if(onInsertCallback->first) + { + ObjectType & owner = *onInsertCallback->first; + void (ObjectType::*cb)(const unsigned int, const ValueType &) = onInsertCallback->second; + (owner.*cb)(element, newValue); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::onSet(const unsigned int element, const ValueType & oldValue, const ValueType & newValue) +{ + if(onSetCallback) + { + if(onSetCallback->first) + { + ObjectType & owner = *onSetCallback->first; + void (ObjectType::*cb)(const unsigned int, const ValueType &, const ValueType &) = onSetCallback->second; + (owner.*cb)(element, oldValue, newValue); + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::pack(ByteStream & target) const +{ + Archive::put(target, v.size()); + Archive::put(target, baselineCommandCount); + typename std::vector::const_iterator i; + for (i = v.begin(); i != v.end(); ++i) + { + Archive::put(target, (*i)); + } +} + +// ---------------------------------------------------------------------- + +template +inline void AutoDeltaVector::pack(ByteStream & target, const std::vector & data) +{ + Archive::put(target, data.size()); + Archive::put(target, static_cast(0)); // baselineCommandCount + typename std::vector::const_iterator i; + for (i = data.begin(); i != data.end(); ++i) + { + Archive::put(target, *i); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::packDelta(ByteStream & target) const +{ + Archive::put(target, commands.size()); + Archive::put(target, baselineCommandCount); + typename std::vector::iterator i; + + for (i = commands.begin(); i != commands.end(); ++i) + { + const Command & c = (*i); + Archive::put(target, c.cmd); + switch(c.cmd) + { + case Command::ERASE: + Archive::put(target, c.index); + break; + case Command::INSERT: + Archive::put(target, c.index); + Archive::put(target, c.value); + break; + case Command::SET: + Archive::put(target, c.index); + Archive::put(target, c.value); + break; + case Command::SETALL: + { + Archive::put(target, c.index); // size + for (unsigned int j = 0; j < c.index; ++j) + { + ++i; + Archive::put(target, (*i).value); + } + } + break; + case Command::CLEAR: + break; + } + } + clearDelta(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::pop_back() +{ + if (v.size() > 0) + AutoDeltaVector::erase(v.size() - 1); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::push_back(const ValueType & t) +{ + AutoDeltaVector::insert(v.size(), t); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaVector::const_reverse_iterator AutoDeltaVector::rbegin() const +{ + return v.rbegin(); +} + +//----------------------------------------------------------------------- + +template +inline typename AutoDeltaVector::const_reverse_iterator AutoDeltaVector::rend() const +{ + return v.rend(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::reserve(size_type n) +{ + v.reserve(n); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::resize(size_type n, ValueType x) +{ + size_type size = v.size(); + if (size < n) + { + // expand the vector + v.resize(n); + for (size_t i = size; i < n; ++i) + set(i, x); + } + else if (size > n) + { + // contract the vector + for (size_t i = size - 1; i >= n; --i) + { + erase(i); + + //-- must do this since our counter is unsigned + if (i == 0) + break; + } + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::set(const unsigned int element, const ValueType & newValue) +{ + if (element < v.size () && v[element] == newValue) + return; + + Command c; + c.cmd = Command::SET; + c.index = static_cast(element); + c.value = newValue; + commands.push_back(c); + ++baselineCommandCount; + + if(element >= v.size()) + v.resize(element + 1); + + ValueType old = v[element]; + + v[element] = newValue; + touch(); + onSet(element, old, newValue); + onChanged(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::set(const VectorType & newValue) +{ + Command c; + c.cmd = Command::SETALL; + c.index = static_cast(newValue.size()); + commands.push_back(c); + ++baselineCommandCount; + + v = newValue; + + for (unsigned int i = 0; i < newValue.size(); ++i) + { + c.cmd = Command::SET; + c.index = static_cast(i); + c.value = v[i]; + commands.push_back(c); + ++baselineCommandCount; + } + + touch(); + onChanged(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::setOnChanged(ObjectType * owner, void (ObjectType::*cb)()) +{ + delete onChangedCallback; + onChangedCallback = new std::pair; + onChangedCallback->first = owner; + onChangedCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::setOnErase(ObjectType * owner, void (ObjectType::*cb)(const unsigned int, const ValueType &)) +{ + delete onEraseCallback; + onEraseCallback = new std::pair; + onEraseCallback->first = owner; + onEraseCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::setOnInsert(ObjectType * owner, void (ObjectType::*cb)(const unsigned int, const ValueType &)) +{ + delete onInsertCallback; + onInsertCallback = new std::pair; + onInsertCallback->first = owner; + onInsertCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::setOnSet(ObjectType * owner, void (ObjectType::*cb)(const unsigned int, const ValueType &, const ValueType &)) +{ + delete onSetCallback; + onSetCallback = new std::pair; + onSetCallback->first = owner; + onSetCallback->second = cb; +} + +//----------------------------------------------------------------------- + +template +inline bool AutoDeltaVector::empty() const +{ + return v.empty(); +} + +//----------------------------------------------------------------------- + +template +inline const size_t AutoDeltaVector::size() const +{ + return v.size(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::unpack(ReadIterator & source) +{ + // unpacking the whole kazaba + v.clear(); + clearDelta(); + + size_t commandCount; + ValueType value; + + Archive::get(source, commandCount); + Archive::get(source, baselineCommandCount); + + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source, value); + v.push_back(value); + } + + onChanged(); +} + +// ---------------------------------------------------------------------- + +template +inline void AutoDeltaVector::unpack(ReadIterator & source, std::vector & data) +{ + // unpacking the whole kazaba + size_t commandCount; + size_t bcc; + Command c; + + Archive::get(source, commandCount); + Archive::get(source, bcc); + + for (size_t i = 0; i < commandCount; ++i) + { + Archive::get(source,c.value); + c.index = static_cast(i); + c.cmd = Command::INSERT; + + data.push_back(c); + } +} + +// ---------------------------------------------------------------------- + +template +inline void AutoDeltaVector::unpackDelta(ReadIterator & source, std::vector & data) +{ + Command c; + size_t commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + for (size_t i=0 ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch (c.cmd) + { + case Command::ERASE: + Archive::get(source, c.index); + break; + case Command::INSERT: + Archive::get(source, c.index); + Archive::get(source, c.value); + break; + case Command::SET: + Archive::get(source, c.index); + Archive::get(source, c.value); + break; + case Command::SETALL: // SETALL is not supported by the static AutoDeltaVector unpack function, because there's no place to put the value + assert(false); + case Command::CLEAR: + break; + default: + assert(false); + break; + } + data.push_back(c); + } +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVector::unpackDelta(ReadIterator & source) +{ + Command c; + size_t skipCount, commandCount, targetBaselineCommandCount; + + Archive::get(source, commandCount); + Archive::get(source, targetBaselineCommandCount); + + skipCount = commandCount+baselineCommandCount-targetBaselineCommandCount; + + // note: SETALL commands come across with a command count of 1+newsize + if (skipCount > commandCount) + skipCount = commandCount; + + size_t i; + for (i = 0; i < skipCount; ++i) + { + Archive::get(source, c.cmd); + if (c.cmd != Command::CLEAR) + Archive::get(source, c.index); + if (c.cmd == Command::SETALL) + { + for (unsigned int j = 0; j < c.index; ++j) + { + ++i; + Archive::get(source, c.value); + } + } + else if (c.cmd != Command::ERASE && c.cmd != Command::CLEAR) + Archive::get(source, c.value); + } + for ( ; i < commandCount; ++i) + { + Archive::get(source, c.cmd); + switch (c.cmd) + { + case Command::ERASE: + { + Archive::get(source, c.index); + AutoDeltaVector::erase(c.index); + } + break; + case Command::INSERT: + { + Archive::get(source, c.index); + Archive::get(source, c.value); + AutoDeltaVector::insert(c.index, c.value); + } + break; + case Command::SET: + { + Archive::get(source, c.index); + Archive::get(source, c.value); + AutoDeltaVector::set(c.index, c.value); + } + break; + case Command::SETALL: + { + Archive::get(source, c.index); // size + VectorType tempVec; + tempVec.reserve(c.index); + ValueType value; + for (unsigned int j = 0; j < c.index; ++j) + { + ++i; + Archive::get(source, value); + tempVec.push_back(value); + } + AutoDeltaVector::set(tempVec); + } + break; + case Command::CLEAR: + AutoDeltaVector::clear(); + break; + } + } +} + +//--------------------------------------------------------------------- + +template +inline const ValueType & AutoDeltaVector::operator[] (const unsigned int element) const +{ + return get(element); +} + +//--------------------------------------------------------------------- + +}//namespace Archive + +#endif // _INCLUDED__AutoDeltaVector_H + diff --git a/external/ours/library/archive/src/shared/AutoDeltaVectorObserver.h b/external/ours/library/archive/src/shared/AutoDeltaVectorObserver.h new file mode 100644 index 00000000..75447dc6 --- /dev/null +++ b/external/ours/library/archive/src/shared/AutoDeltaVectorObserver.h @@ -0,0 +1,192 @@ +#ifndef _INCLUDED_AutoDeltaVectorObserver_H +#define _INCLUDED_AutoDeltaVectorObserver_H + +#include "AutoDeltaVector.h" +#include "AutoDeltaObserverOps.h" + +namespace Archive { + +/** + @brief an authoritative variable that provides notification both prior to and after change +*/ + +template +class AutoDeltaVectorObserver : public AutoDeltaVector +{ +public: + + typedef std::vector VectorType; + + AutoDeltaVectorObserver(); + AutoDeltaVectorObserver(const AutoDeltaVectorObserver & source); + explicit AutoDeltaVectorObserver(const ValueType & source); + ~AutoDeltaVectorObserver(); + + AutoDeltaVectorObserver & operator = (const AutoDeltaVectorObserver & source); + AutoDeltaVectorObserver & operator = (const ValueType & source); + + void setSourceObject(SourceObjectType * source); + + virtual void clear (); + virtual void erase (const unsigned int element); + virtual void pop_back (); + virtual void push_back (const ValueType & t); + virtual void insert (const unsigned int before, const ValueType &newValue); + virtual void set (const unsigned int element, const ValueType &source); + virtual void set (const VectorType & newValue); + virtual void unpack (ReadIterator & source); + virtual void unpackDelta (ReadIterator & source); + +private: + SourceObjectType* sourceObject; +}; + +//---------------------------------------------------------------- + +template +inline AutoDeltaVectorObserver::AutoDeltaVectorObserver() : +AutoDeltaVector(), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVectorObserver::AutoDeltaVectorObserver(const AutoDeltaVectorObserver & source) : +AutoDeltaVector(source), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVectorObserver::AutoDeltaVectorObserver(const ValueType & source) : +AutoDeltaVector(source), +sourceObject(0) +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVectorObserver::~AutoDeltaVectorObserver() +{ +} + +//---------------------------------------------------------------- + +template +inline AutoDeltaVectorObserver & AutoDeltaVectorObserver::operator =(const AutoDeltaVectorObserver & rhs) +{ + if (&rhs != this) + set(rhs.get()); + return *this; +} + +//----------------------------------------------------------------------- + +template +inline AutoDeltaVectorObserver & AutoDeltaVectorObserver::operator = (const ValueType & rhs) +{ + if (rhs != this->get()) + set(rhs); + return *this; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::setSourceObject(SourceObjectType * source) +{ + sourceObject = source; +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::clear() +{ + Callback callback(sourceObject, ADOO_clear); + AutoDeltaVector::clear(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::erase(const unsigned int element) +{ + Callback callback(sourceObject, ADOO_erase); + AutoDeltaVector::erase(element); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::pop_back() +{ + Callback callback(sourceObject, ADOO_pop_back); + AutoDeltaVector::pop_back(); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::push_back(const ValueType & t) +{ + Callback callback(sourceObject, ADOO_push_back); + AutoDeltaVector::push_back(t); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::insert(const unsigned int before, const ValueType &newValue) +{ + Callback callback(sourceObject, ADOO_insert); + AutoDeltaVector::insert(before, newValue); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::set(const unsigned int element, const ValueType & source) +{ + Callback callback(sourceObject, ADOO_set); + AutoDeltaVector::set(element, source); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::set(const VectorType &newValue) +{ + Callback callback(sourceObject, ADOO_setAll); + AutoDeltaVector::set(newValue); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::unpack(ReadIterator & source) +{ + Callback callback(sourceObject, ADOO_unpack); + AutoDeltaVector::unpack(source); +} + +//----------------------------------------------------------------------- + +template +inline void AutoDeltaVectorObserver::unpackDelta(ReadIterator & source) +{ + Callback callback(sourceObject, ADOO_unpackDelta); + AutoDeltaVector::unpackDelta(source); +} + +//----------------------------------------------------------------------- + +} + +#endif + diff --git a/external/ours/library/archive/src/shared/ByteStream.cpp b/external/ours/library/archive/src/shared/ByteStream.cpp new file mode 100644 index 00000000..97e0c8fe --- /dev/null +++ b/external/ours/library/archive/src/shared/ByteStream.cpp @@ -0,0 +1,371 @@ +//--------------------------------------------------------------------- +#include "FirstArchive.h" +#include "ByteStream.h" +#include "ArchiveMutex.h" +#include + +// ====================================================================== + +//static volatile int s_dataFreeListLocked; +static Archive::ArchiveMutex s_archiveMutex; + + +// ====================================================================== + +namespace Archive { + +//--------------------------------------------------------------------- +/** + @brief ReadIterator ctor + + Initializes the read position to zero, and the ByteStream member value + is NULL +*/ +ReadIterator::ReadIterator() : + readPtr(0), + stream(0) +{ +} + +//--------------------------------------------------------------------- +/** + @brief ReadIterator copy constructor + + Sets the current position to the source read position and the + ByteStream pointer to the source ByteStream. +*/ +ReadIterator::ReadIterator(const ReadIterator & source) : + readPtr(source.readPtr), + stream(source.stream) +{ +} + + +//--------------------------------------------------------------------- +/** + @brief construct a read iterator with the position at zero and + the ByteStream set to the source. +*/ +ReadIterator::ReadIterator(ByteStream const &source) : + readPtr(0), + stream(&source) +{ +} + +//--------------------------------------------------------------------- +/** + @brief destroy a read iterator object, set the ByteStream member to + zero. +*/ +ReadIterator::~ReadIterator() +{ + stream = 0; +} + +//--------------------------------------------------------------------- +/** + Comparison operator + + Indicates whether the two iterators point to the same place in the + same bytestream. + + @author Acy Stapp +*/ +bool ReadIterator::operator==(ReadIterator const &rhs) const +{ + // We are almost guaranteed to be comparing iterators from the same + // bytestream, so we put that test last, giving the other test a + // chance to fail and avoid the almost certainty. + if (readPtr != rhs.readPtr) + return false; + return stream == rhs.stream; +} + +//--------------------------------------------------------------------- +/** + Construct an ByteStream object. + + This constructor merely initializes members, No buffer allocation + occurs. + + @author Justin Randall +*/ +ByteStream::ByteStream() : + allocatedSize(0), + allocatedSizeLimit(0), + beginReadIterator(), + data(0), + size(0) +{ + beginReadIterator = ReadIterator(*this); +} + +//--------------------------------------------------------------------- +/** + @brief Construct an ByteStream from a byte buffer + + @author Justin Randall +*/ +ByteStream::ByteStream(unsigned char const * const newBuffer, const unsigned int bufferSize) : + allocatedSize(bufferSize), + allocatedSizeLimit(0), + data(0), + size(bufferSize) +{ + data = Data::getNewData(); + if (data->size < size) + { + delete[] data->buffer; + + if(size > 0) + data->buffer = new unsigned char[size]; + else + data->buffer = 0; + + data->size = size; + } + + if (size > 0) + memcpy(data->buffer, newBuffer, size); + + beginReadIterator = ReadIterator(*this); +} + +//--------------------------------------------------------------------- +/** + ByteStream Copy Constructor +*/ +ByteStream::ByteStream(ByteStream const &source): + allocatedSize(source.getSize()), // only allocate what is really there, be opportinistic when grow()'ing + allocatedSizeLimit(0), + data(source.data), + size(source.getSize()) +{ + if (source.data) + source.data->ref(); + beginReadIterator = ReadIterator(*this); +} + +//----------------------------------------------------------------------- +/** + @brief ByteStream copy constructor + + Creates a new byte stream, deep copying the source stream from the + source read iterator. + +*/ +ByteStream::ByteStream(ReadIterator &source) : + allocatedSize(0), + allocatedSizeLimit(0), + data(Data::getNewData()), + size(0) +{ + put(source.getBuffer(), source.getSize()); + source.advance(source.getSize()); + beginReadIterator = ReadIterator(*this); +} + +//--------------------------------------------------------------------- +/** + ByteStream destructor + + Deletes the assocated buffer and resets allocateSize, buffer, and + size to zero. + + @author Justin Randall +*/ +ByteStream::~ByteStream() +{ + if (data) + { + data->deref(); + data = 0; //lint !e672 (data deref insures the data is deleted if no one references it) + } + allocatedSize = 0; + size = 0; +} + +//--------------------------------------------------------------------- +/** + Assignment operator + + If the ByteStream right hand side is not the same ByteStream, performs + a deep copy of the ByteStream. + + @author Justin Randall +*/ +ByteStream &ByteStream::operator=(ByteStream const &rhs) +{ + if (this != &rhs) + { + if (data) + data->deref(); // deref local data + if (rhs.data) + rhs.data->ref(); + allocatedSize = rhs.allocatedSize; + allocatedSizeLimit = rhs.allocatedSizeLimit; + size = rhs.size; + data = rhs.data; //lint !e672 (data is ref counted) + } + return *this; +} + +//--------------------------------------------------------------------- +/** + @brief Accesses ByteStream data + + @param target a user supplied buffer that must be at least as + large as targetSize + @param readIterator An accessor that indicates where the read operation + will begin + @param targetSize specifies the number of bytes to read from the + ByteStream + + @author Justin Randall +*/ +void ByteStream::get(void *target, ReadIterator &readIterator, const unsigned long int targetSize) const +{ + if (data && readIterator.getReadPosition() + targetSize <= allocatedSize) + { + memcpy(target, &data->buffer[readIterator.getReadPosition()], targetSize); + } + else + { + static const char * const desc = "Archive::ByteStream - read beyond end of buffer"; + ReadException ex(desc); + throw (ex); + } +} + +//--------------------------------------------------------------------- +/** + @brief deep copy new data to the ByteStream + + If the data member is shared with another ByteStream, then it is + copied before this operation begins. The ByteStream buffer is increased + to hold the new data (determined by the requested sourceSize). + + @param source a user supplied buffer that contains data to be + copied to the ByteStream + @param sourceSize The number of bytes in the source buffer which + will be copied to the ByteStream. + + @author Justin Randall +*/ +void ByteStream::put(void const * const source, const unsigned int sourceSize) +{ + if (!data) + data = Data::getNewData(); + + if (data->getRef() > 1) + { + unsigned char const * const tmp = data->buffer; + data->deref(); + data = Data::getNewData(); + if (data->size < sourceSize) + { + delete[] data->buffer; + + if (size > 0) + data->buffer = new unsigned char[size]; + else + data->buffer = 0; + + data->size = size; + } + + if (size > 0) + memcpy(data->buffer, tmp, size); + + allocatedSize = size; + } + growToAtLeast(size + sourceSize); + memcpy(&data->buffer[size], source, sourceSize); + size += sourceSize; +} + +//--------------------------------------------------------------------- + +void ByteStream::reAllocate(const unsigned int newSize) +{ + allocatedSize = newSize; + if (!data) + data = Data::getNewData(); + + if (data->size < allocatedSize) + { + unsigned char * tmp = new unsigned char[newSize]; + if (data->buffer) + memcpy(tmp, data->buffer, size); + delete[] data->buffer; + data->buffer = tmp; + data->size = newSize; + } +} + +//--------------------------------------------------------------------- + +std::vector &ByteStream::Data::lockDataFreeList() +{ + static DataFreeList freeList; + s_archiveMutex.enter(); + return freeList.freeList; +} + +//----------------------------------------------------------------------- + +void ByteStream::Data::unlockDataFreeList() +{ + s_archiveMutex.leave(); +} + +//----------------------------------------------------------------------- + +ByteStream::Data *ByteStream::Data::getNewData() +{ + Data *result = 0; + std::vector &dataFreeList = lockDataFreeList(); + if (dataFreeList.empty()) + { + unlockDataFreeList(); + result = new Data; + } + else + { + result = dataFreeList.back(); + dataFreeList.pop_back(); + unlockDataFreeList(); + } + result->refCount = 1; + return result; +} + +//--------------------------------------------------------------------- + +void ByteStream::Data::releaseOldData(ByteStream::Data *oldData) +{ + assert(reinterpret_cast(oldData) != 0xefefefefu); + + if (oldData->size > 4096) + delete oldData; + else + { + std::vector &dataFreeList = lockDataFreeList(); + + if (dataFreeList.size() > 256) + delete oldData; + else + { + oldData->refCount = 0; + dataFreeList.push_back(oldData); + } + + unlockDataFreeList(); + } +} + +//--------------------------------------------------------------------- + +}//namespace Archive + +//--------------------------------------------------------------------- diff --git a/external/ours/library/archive/src/shared/ByteStream.h b/external/ours/library/archive/src/shared/ByteStream.h new file mode 100644 index 00000000..ec360ca0 --- /dev/null +++ b/external/ours/library/archive/src/shared/ByteStream.h @@ -0,0 +1,408 @@ +#ifndef _ByteStream_H +#define _ByteStream_H + +//--------------------------------------------------------------------- +#if WIN32 +#pragma warning ( disable : 4786 ) // dentifier was truncated to '255' characters in the debug information +#pragma warning ( disable : 4514 ) // inlined function has been removed +#endif + +#include + +//--------------------------------------------------------------------- + +namespace Archive +{ + + + +//--------------------------------------------------------------------- + +class ReadException : public std::exception +{ +public: + explicit ReadException(const char * const what); + ReadException(const ReadException & source); + ReadException & operator = (const ReadException & rhs); + ~ReadException() throw(); + + const char * what() const throw(); + +private: + const char * m_what; +}; + +//--------------------------------------------------------------------- + +inline ReadException::ReadException(const char * what) : +m_what(what) +{ +} + +//--------------------------------------------------------------------- + +inline ReadException::ReadException(const ReadException & source) : +m_what(source.m_what) +{ +} + +//--------------------------------------------------------------------- + +inline ReadException::~ReadException() throw() +{ +} + +//--------------------------------------------------------------------- + +inline ReadException & ReadException::operator = (const ReadException & rhs) +{ + m_what = rhs.m_what; + return *this; +} + +//--------------------------------------------------------------------- + +inline const char * ReadException::what() const throw() +{ + return m_what; +} + +class ByteStream; + +class ReadIterator +{ +public: + ReadIterator (); + ReadIterator (const ReadIterator & source); + explicit ReadIterator (const ByteStream & source); + ~ReadIterator (); + + ReadIterator & operator = (const ReadIterator & source); + bool operator == (const ReadIterator & other) const; + bool operator != (const ReadIterator & other) const; + void advance (const unsigned int distance); + void get (void * target, const unsigned long int readSize); + const unsigned int getSize () const; + const unsigned char * const getBuffer () const; + const unsigned int getReadPosition () const; +private: + + unsigned int readPtr; + const ByteStream * stream; +}; + +inline bool ReadIterator::operator != (const ReadIterator &other) const +{ + return !(*this == other); +} + +//--------------------------------------------------------------------- +/** \class ByteStream ByteStream.h "Archive/ByteStream.h" + @brief A byte ByteStream +*/ +class ByteStream +{ +public: // ctor/dtors + ByteStream(); + ByteStream(const unsigned char * const buffer, const unsigned int bufferSize); + ByteStream(const ByteStream & source); + virtual ~ByteStream(); + + typedef Archive::ReadIterator ReadIterator; + +public: // inner classes + /** \class ReadIterator ByteStream.h "Archive/ByteStream.h" + @brief an iterator object used to retrieve data from a ByteStream + + The ReadIterator is employed to coordinate multiple consumers of + a ByteStream object without altering the ByteStream itself. It is a const-like + iterator that will not change the contents of a ByteStream. Multiple ByteStream + consumers may access data in the ByteStream using ReadIterators. + + @author Justin Randall + */ + +public: + ByteStream(ReadIterator & source); + ByteStream & operator = (const ByteStream & source); + ByteStream & operator = (ReadIterator & source); + const ReadIterator & begin() const; + const ReadIterator end() const; + void clear(); + const unsigned char * const getBuffer() const; + const unsigned int getSize() const; + void put(const void * const source, const unsigned int sourceSize); + void setAllocatedSizeLimit(unsigned int limit); + +private: + void get(void * target, ReadIterator & readIterator, const unsigned long int readSize) const; + void growToAtLeast(const unsigned int targetSize); + void reAllocate(const unsigned int newSize); + +private: // inner classes + class Data + { + public: + ~Data(); + + static Data * getNewData(); + + const int getRef () const; + void deref (); + void ref (); + protected: + friend class ByteStream; + friend class Archive::ReadIterator; + unsigned char * buffer; + unsigned long size; + private: + struct DataFreeList + { + ~DataFreeList() + { + std::vector::iterator i; + for(i = freeList.begin(); i != freeList.end(); ++i) + { + delete (*i); + } + }; + std::vector freeList; + }; + Data(); +// explicit Data(unsigned char * buffer); + static std::vector & lockDataFreeList(); + static void unlockDataFreeList(); + static void releaseOldData(Data * oldData); + + private: + int refCount; + }; + +private: + friend class Archive::ReadIterator; + unsigned int allocatedSize; + unsigned int allocatedSizeLimit; + ReadIterator beginReadIterator; + Data * data; + unsigned int size; +}; //lint !e1934 + +//--------------------------------------------------------------------- + +inline ByteStream::Data::Data() : +buffer(0), +size(0), +refCount(1) +{ +} + +//--------------------------------------------------------------------- +/* +inline ByteStream::Data::Data(unsigned char * newBuffer) : +buffer(newBuffer), +refCount(1) +{ +} +*/ +//--------------------------------------------------------------------- + +inline ByteStream::Data::~Data() +{ + refCount = 0; + delete[] buffer; +} + +//--------------------------------------------------------------------- + +inline void ByteStream::Data::deref() +{ + refCount--; + if(refCount < 1) + releaseOldData(this); +// delete this; + +} + +//----------------------------------------------------------------------- + +inline const int ByteStream::Data::getRef() const +{ + return refCount; +} + +//--------------------------------------------------------------------- + +inline void ByteStream::Data::ref() +{ + refCount++; +} + +//----------------------------------------------------------------------- + +inline ReadIterator & ReadIterator::operator = (const ReadIterator & rhs) +{ + if(&rhs != this) + { + readPtr = rhs.readPtr; + stream = rhs.stream; + } + return *this; +} + +//--------------------------------------------------------------------- + +inline void ReadIterator::get(void * target, const unsigned long int readSize) +{ + if(stream) + { + stream->get(target, *this, readSize); + readPtr += readSize; + } + else + { + static const char * const desc = "Archive::ReadIterator::get - read operation on null stream object"; + ReadException ex(desc); + throw (ex); + } +} + +//--------------------------------------------------------------------- + +inline const unsigned int ReadIterator::getSize() const +{ + if(stream) + return stream->getSize() - readPtr; + return 0; +} + +//--------------------------------------------------------------------- + +inline const ReadIterator & ByteStream::begin() const +{ + return beginReadIterator; +} + +//--------------------------------------------------------------------- + +inline const ReadIterator ByteStream::end() const +{ + ReadIterator result(*this); + result.advance(size); + return result; +} + +//--------------------------------------------------------------------- + +inline void ReadIterator::advance(const unsigned int distance) +{ + readPtr += distance; +} + +//--------------------------------------------------------------------- + +inline const unsigned int ReadIterator::getReadPosition() const +{ + return readPtr; +} + +//--------------------------------------------------------------------- + +inline const unsigned char * const ReadIterator::getBuffer() const +{ + if(stream && stream->data) + return &stream->data->buffer[readPtr]; + + return 0; +} + +//--------------------------------------------------------------------- +/** + @brief clear read and write settings for the ByteStream + + This does not free allocated memory. Instead, it keeps the ByteStream + buffer and sets the read and write pointers back to the beginning + of the ByteStream + + @author Justin Randall +*/ +inline void ByteStream::clear() +{ + size = 0; + + if ((allocatedSizeLimit) && (allocatedSize > allocatedSizeLimit)) + { + if (data) + { + data->deref(); + data = 0; + } + allocatedSize = 0; + + reAllocate(allocatedSizeLimit); + } +} + +//--------------------------------------------------------------------- +/** + @brief get the whole ByteStream buffer (very const) +*/ +inline const unsigned char * const ByteStream::getBuffer() const +{ + if (data) + return data->buffer; + return 0; +} + +//--------------------------------------------------------------------- +/** + @brief Get the size, in bytes, of the ByteStream buffer + + @return the size, in bytes, of the ByteStream buffer + + @author Justin Randall +*/ +inline const unsigned int ByteStream::getSize() const +{ + return size; +} + +//--------------------------------------------------------------------- +/** + This private method ensures that the ByteStream buffer is large enough + to receive data at least as large as the requested targetSize. + + @param unsigned int targetSize The desired size to increase the + ByteStream buffer. + + @author Justin Randall +*/ + +inline void ByteStream::growToAtLeast(const unsigned int targetSize) +{ + if(allocatedSize < targetSize) + { + if(allocatedSize < 4096) + { + reAllocate(allocatedSize + allocatedSize + targetSize); + } + else + { + reAllocate(allocatedSize + targetSize); + } + } +} + +//--------------------------------------------------------------------- + +inline void ByteStream::setAllocatedSizeLimit(const unsigned int limit) +{ + allocatedSizeLimit = limit; + + if ((allocatedSizeLimit) && (allocatedSize < allocatedSizeLimit)) + reAllocate(allocatedSizeLimit); +} + +} // namespace Archive +//--------------------------------------------------------------------- + +#endif // _ByteStream_H diff --git a/external/ours/library/archive/src/shared/FirstArchive.h b/external/ours/library/archive/src/shared/FirstArchive.h new file mode 100644 index 00000000..81a3e61b --- /dev/null +++ b/external/ours/library/archive/src/shared/FirstArchive.h @@ -0,0 +1,19 @@ +// FirstArchive.h +// copyright 2001 Verant Interactive +// Author: Justin Randall + +#ifndef _INCLUDED_FirstArchive_H +#define _INCLUDED_FirstArchive_H + +//----------------------------------------------------------------------- + +#pragma warning ( disable : 4514 ) // unreferenced inline function has been removed +#pragma warning ( disable : 4710 ) // not inlined +#pragma warning ( disable : 4702 ) // unreachable code +#include "Archive.h" +#include "ByteStream.h" +#include + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_FirstArchive_H diff --git a/external/ours/library/archive/src/win32/ArchiveMutex.cpp b/external/ours/library/archive/src/win32/ArchiveMutex.cpp new file mode 100644 index 00000000..016c070b --- /dev/null +++ b/external/ours/library/archive/src/win32/ArchiveMutex.cpp @@ -0,0 +1,35 @@ +// ====================================================================== +// +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + + +#include "FirstArchive.h" +#include "ArchiveMutex.h" + +namespace Archive +{ + +ArchiveMutex::ArchiveMutex() +{ + InitializeCriticalSection(&m_criticalSection); +} + +ArchiveMutex::~ArchiveMutex() +{ + DeleteCriticalSection(&m_criticalSection); +} + +void ArchiveMutex::enter() +{ + EnterCriticalSection(&m_criticalSection); +} + +void ArchiveMutex::leave() +{ + LeaveCriticalSection(&m_criticalSection); +} + +} diff --git a/external/ours/library/archive/src/win32/ArchiveMutex.h b/external/ours/library/archive/src/win32/ArchiveMutex.h new file mode 100644 index 00000000..b453981b --- /dev/null +++ b/external/ours/library/archive/src/win32/ArchiveMutex.h @@ -0,0 +1,27 @@ +#ifndef _ArchiveMutex_H +#define _ArchiveMutex_H + +#include + +namespace Archive +{ + + class ArchiveMutex + { + public: + + ArchiveMutex(); + ~ArchiveMutex(); + void enter(); + void leave(); + + private: + ArchiveMutex(const ArchiveMutex &o); + ArchiveMutex &operator =(const ArchiveMutex &o); + + CRITICAL_SECTION m_criticalSection; + + }; +} + +#endif diff --git a/external/ours/library/archive/src/win32/FirstArchive.cpp b/external/ours/library/archive/src/win32/FirstArchive.cpp new file mode 100644 index 00000000..6e118e67 --- /dev/null +++ b/external/ours/library/archive/src/win32/FirstArchive.cpp @@ -0,0 +1,16 @@ +// FirstArchive.cpp +// copyright 2001 Verant Interactive +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "FirstArchive.h" + +//----------------------------------------------------------------------- + +namespace +{ + void supress_warning_LNK4221() + { + } +}