Initial commit of the sharedFoundation library
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
shared/ApplicationVersion.cpp
|
||||
shared/ApplicationVersion.h
|
||||
shared/ArrayList.h
|
||||
shared/AutoDeltaNetworkIdPackedMap.cpp
|
||||
shared/AutoDeltaNetworkIdPackedMap.h
|
||||
shared/Binary.h
|
||||
shared/BitArray.cpp
|
||||
shared/BitArray.h
|
||||
shared/Branch.cpp
|
||||
shared/Branch.h
|
||||
shared/CalendarTime.cpp
|
||||
shared/CalendarTime.h
|
||||
shared/CallbackEntryBase.h
|
||||
shared/Clock.cpp
|
||||
shared/Clock.h
|
||||
shared/CommandLine.cpp
|
||||
shared/CommandLine.h
|
||||
shared/ConfigFile.cpp
|
||||
shared/ConfigFile.h
|
||||
shared/ConstCharCrcLowerString.cpp
|
||||
shared/ConstCharCrcLowerString.h
|
||||
shared/ConstCharCrcString.cpp
|
||||
shared/ConstCharCrcString.h
|
||||
shared/CrashReportInformation.cpp
|
||||
shared/CrashReportInformation.h
|
||||
shared/Crc.cpp
|
||||
shared/Crc.h
|
||||
shared/CrcLowerString.cpp
|
||||
shared/CrcLowerString.h
|
||||
shared/CrcString.cpp
|
||||
shared/CrcString.h
|
||||
shared/CrcStringTable.cpp
|
||||
shared/CrcStringTable.h
|
||||
shared/DataResource.cpp
|
||||
shared/DataResource.h
|
||||
shared/DataResourceList.h
|
||||
shared/DebugInfoManager.cpp
|
||||
shared/DebugInfoManager.h
|
||||
shared/ExitChain.cpp
|
||||
shared/ExitChain.h
|
||||
shared/Fatal.cpp
|
||||
shared/Fatal.h
|
||||
shared/FirstSharedFoundation.h
|
||||
shared/FloatMath.h
|
||||
shared/FormattedString.h
|
||||
shared/GameControllerMessage.h
|
||||
shared/LabelHash.cpp
|
||||
shared/LabelHash.h
|
||||
shared/LessPointerComparator.h
|
||||
shared/MacroFoundation.h
|
||||
shared/Md5.cpp
|
||||
shared/Md5.h
|
||||
shared/MemoryBlockManager.cpp
|
||||
shared/MemoryBlockManager.h
|
||||
shared/MemoryBlockManagerMacros.h
|
||||
shared/MessageQueue.cpp
|
||||
shared/MessageQueueDataTemplate.cpp
|
||||
shared/MessageQueueDataTemplate.h
|
||||
shared/MessageQueue.h
|
||||
shared/Misc.h
|
||||
shared/NetworkIdArchive.cpp
|
||||
shared/NetworkIdArchive.h
|
||||
shared/NetworkId.cpp
|
||||
shared/NetworkId.h
|
||||
shared/PersistentCrcString.cpp
|
||||
shared/PersistentCrcString.h
|
||||
shared/PointerDeleter.h
|
||||
shared/Production.h
|
||||
shared/SafeCast.h
|
||||
shared/Scheduler.cpp
|
||||
shared/Scheduler.h
|
||||
shared/StaticCallbackEntry.cpp
|
||||
shared/StaticCallbackEntry.h
|
||||
shared/StationId.h
|
||||
shared/StlForwardDeclaration.h
|
||||
shared/StringCompare.h
|
||||
shared/Tag.h
|
||||
shared/TemporaryCrcString.cpp
|
||||
shared/TemporaryCrcString.h
|
||||
shared/Timer.cpp
|
||||
shared/Timer.h
|
||||
shared/VoidBindSecond.h
|
||||
shared/VoidMemberFunction.h
|
||||
shared/Watcher.cpp
|
||||
shared/Watcher.h
|
||||
|
||||
shared/dynamicVariable/DynamicVariable.cpp
|
||||
shared/dynamicVariable/DynamicVariable.h
|
||||
shared/dynamicVariable/DynamicVariableList.cpp
|
||||
shared/dynamicVariable/DynamicVariableList.h
|
||||
shared/dynamicVariable/DynamicVariableListNestedList.cpp
|
||||
shared/dynamicVariable/DynamicVariableListNestedList.h
|
||||
shared/dynamicVariable/DynamicVariableLocationData.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/ByteOrder.cpp
|
||||
win32/ByteOrder.h
|
||||
win32/ConfigSharedFoundation.cpp
|
||||
win32/ConfigSharedFoundation.h
|
||||
win32/FirstPlatform.h
|
||||
win32/FloatingPointUnit.cpp
|
||||
win32/FloatingPointUnit.h
|
||||
win32/Os.cpp
|
||||
win32/Os.h
|
||||
win32/PerThreadData.cpp
|
||||
win32/PerThreadData.h
|
||||
win32/PlatformGlue.cpp
|
||||
win32/PlatformGlue.h
|
||||
win32/ProcessSpawner.cpp
|
||||
win32/ProcessSpawner.h
|
||||
win32/RegistryKey.cpp
|
||||
win32/RegistryKey.h
|
||||
win32/SetupSharedFoundation.cpp
|
||||
win32/SetupSharedFoundation.h
|
||||
win32/WindowsWrapper.h
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
linux/ByteOrder.h
|
||||
linux/ConfigSharedFoundation.cpp
|
||||
linux/ConfigSharedFoundation.h
|
||||
linux/FirstPlatform.h
|
||||
linux/FloatingPointUnit.cpp
|
||||
linux/FloatingPointUnit.h
|
||||
linux/Os.cpp
|
||||
linux/Os.h
|
||||
linux/PerThreadData.cpp
|
||||
linux/PerThreadData.h
|
||||
linux/PlatformGlue.cpp
|
||||
linux/PlatformGlue.h
|
||||
linux/SetupSharedFoundation.cpp
|
||||
linux/SetupSharedFoundation.h
|
||||
linux/vsnprintf.cpp
|
||||
linux/vsnprintf.h
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/linux)
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/shared)
|
||||
|
||||
add_library(sharedFoundation
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ByteOrder.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef BYTE_ORDER_H
|
||||
#define BYTE_ORDER_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstPlatform.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigSharedFoundation.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const int c_defaultFatalCallStackDepth = 32;
|
||||
const int c_defaultWarningCallStackDepth = 8;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace ConfigSharedFoundationNamespace
|
||||
{
|
||||
real ms_frameRateLimit;
|
||||
real ms_minFrameRate;
|
||||
bool ms_noExceptionHandling;
|
||||
|
||||
bool ms_fpuExceptionPrecision;
|
||||
bool ms_fpuExceptionUnderflow;
|
||||
bool ms_fpuExceptionOverflow;
|
||||
bool ms_fpuExceptionZeroDivide;
|
||||
bool ms_fpuExceptionDenormal;
|
||||
bool ms_fpuExceptionInvalid;
|
||||
|
||||
bool ms_demoMode;
|
||||
|
||||
bool ms_useRemoteDebug;
|
||||
int ms_defaultRemoteDebugPort;
|
||||
|
||||
bool ms_profilerExpandAllBranches = true;
|
||||
|
||||
bool ms_memoryManagerReportAllocations;
|
||||
bool ms_memoryManagerReportOnOutOfMemory;
|
||||
|
||||
bool ms_useMemoryBlockManager;
|
||||
bool ms_memoryBlockManagerDebugDumpOnRemove;
|
||||
|
||||
int ms_fatalCallStackDepth;
|
||||
int ms_warningCallStackDepth;
|
||||
bool ms_lookUpCallStackNames;
|
||||
|
||||
bool ms_alwaysCanSeeWorldCell;
|
||||
|
||||
bool ms_verboseWarnings;
|
||||
|
||||
float ms_debugReportLongFrameTime;
|
||||
}
|
||||
|
||||
using namespace ConfigSharedFoundationNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define KEY_INT(a,b) (ms_ ## a = ConfigFile::getKeyInt("SharedFoundation", #a, b))
|
||||
#define KEY_BOOL(a,b) (ms_ ## a = ConfigFile::getKeyBool("SharedFoundation", #a, b))
|
||||
#define KEY_FLOAT(a,b) (ms_ ## a = ConfigFile::getKeyFloat("SharedFoundation", #a, b))
|
||||
// #define KEY_STRING(a,b) (ms_ ## a = ConfigFile::getKeyString("SharedFoundation", #a, b))
|
||||
|
||||
// ======================================================================
|
||||
// Determine the Platform-specific configuration information
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine inspects the ConfigFile class to set some variables for rapid access
|
||||
// by the rest of the engine.
|
||||
|
||||
void ConfigSharedFoundation::install (const Defaults &defaults)
|
||||
{
|
||||
KEY_BOOL(noExceptionHandling, false);
|
||||
|
||||
KEY_BOOL(fpuExceptionPrecision, false);
|
||||
KEY_BOOL(fpuExceptionUnderflow, false);
|
||||
KEY_BOOL(fpuExceptionOverflow, false);
|
||||
KEY_BOOL(fpuExceptionZeroDivide, false);
|
||||
KEY_BOOL(fpuExceptionDenormal, false);
|
||||
KEY_BOOL(fpuExceptionInvalid, false);
|
||||
|
||||
KEY_BOOL(demoMode, false);
|
||||
|
||||
KEY_FLOAT(frameRateLimit, defaults.frameRateLimit);
|
||||
KEY_FLOAT(minFrameRate, 0.0f);
|
||||
|
||||
KEY_BOOL(useRemoteDebug, false);
|
||||
KEY_INT(defaultRemoteDebugPort, 4445);
|
||||
|
||||
KEY_BOOL(profilerExpandAllBranches, true);
|
||||
KEY_BOOL(memoryManagerReportAllocations, true);
|
||||
KEY_BOOL(memoryManagerReportOnOutOfMemory, true);
|
||||
|
||||
KEY_BOOL(useMemoryBlockManager, true);
|
||||
KEY_BOOL(memoryBlockManagerDebugDumpOnRemove, false);
|
||||
|
||||
KEY_INT(fatalCallStackDepth, c_defaultFatalCallStackDepth);
|
||||
KEY_INT(warningCallStackDepth, c_defaultWarningCallStackDepth);
|
||||
KEY_BOOL(lookUpCallStackNames, true);
|
||||
|
||||
KEY_BOOL(alwaysCanSeeWorldCell, false);
|
||||
|
||||
KEY_BOOL(verboseWarnings, false);
|
||||
|
||||
KEY_FLOAT(debugReportLongFrameTime, 0.25f);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Return the frame rate limit value for the game.
|
||||
*
|
||||
* @return The initial frame rate limiter value
|
||||
*/
|
||||
|
||||
real ConfigSharedFoundation::getFrameRateLimit(void)
|
||||
{
|
||||
return ms_frameRateLimit;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the minimum frame rate limit value for the game. Frame that take longer
|
||||
* will be set to the minimum and a message will be logged.
|
||||
*
|
||||
* @return The minimum frame rate value
|
||||
*/
|
||||
|
||||
real ConfigSharedFoundation::getMinFrameRate(void)
|
||||
{
|
||||
return ms_minFrameRate;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return whether to run with exception handling enabled.
|
||||
*
|
||||
* @return True to run without exception handling
|
||||
*/
|
||||
|
||||
bool ConfigSharedFoundation::getNoExceptionHandling(void)
|
||||
{
|
||||
return ms_noExceptionHandling;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionPrecision(void)
|
||||
{
|
||||
return ms_fpuExceptionPrecision;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionUnderflow(void)
|
||||
{
|
||||
return ms_fpuExceptionUnderflow;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionOverflow(void)
|
||||
{
|
||||
return ms_fpuExceptionOverflow;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionZeroDivide(void)
|
||||
{
|
||||
return ms_fpuExceptionZeroDivide;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionDenormal(void)
|
||||
{
|
||||
return ms_fpuExceptionDenormal;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getFpuExceptionInvalid(void)
|
||||
{
|
||||
return ms_fpuExceptionInvalid;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ConfigSharedFoundation::getFatalCallStackDepth()
|
||||
{
|
||||
return ms_fatalCallStackDepth;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ConfigSharedFoundation::getWarningCallStackDepth()
|
||||
{
|
||||
return ms_warningCallStackDepth;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getProfilerExpandAllBranches()
|
||||
{
|
||||
return ms_profilerExpandAllBranches;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getUseRemoteDebug()
|
||||
{
|
||||
return ms_useRemoteDebug;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int ConfigSharedFoundation::getDefaultRemoteDebugPort()
|
||||
{
|
||||
return ms_defaultRemoteDebugPort;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getDemoMode()
|
||||
{
|
||||
return ms_demoMode;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getAlwaysCanSeeWorldCell()
|
||||
{
|
||||
return ms_alwaysCanSeeWorldCell;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getLookUpCallStackNames()
|
||||
{
|
||||
return ms_lookUpCallStackNames;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getMemoryManagerReportAllocations()
|
||||
{
|
||||
return ms_memoryManagerReportAllocations;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getMemoryManagerReportOnOutOfMemory()
|
||||
{
|
||||
return ms_memoryManagerReportOnOutOfMemory;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getUseMemoryBlockManager()
|
||||
{
|
||||
return ms_useMemoryBlockManager;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getMemoryBlockManagerDebugDumpOnRemove ()
|
||||
{
|
||||
return ms_memoryBlockManagerDebugDumpOnRemove;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ConfigSharedFoundation::getVerboseWarnings()
|
||||
{
|
||||
return ms_verboseWarnings;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
float ConfigSharedFoundation::getDebugReportLongFrameTime()
|
||||
{
|
||||
return ms_debugReportLongFrameTime;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,64 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigSharedFoundation.h
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConfigSharedFoundation_H
|
||||
#define INCLUDED_ConfigSharedFoundation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ConfigSharedFoundation
|
||||
{
|
||||
public:
|
||||
|
||||
struct Defaults
|
||||
{
|
||||
real frameRateLimit;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static void install (const Defaults &defaults);
|
||||
|
||||
static real getFrameRateLimit();
|
||||
static real getMinFrameRate();
|
||||
static bool getNoExceptionHandling();
|
||||
|
||||
static bool getFpuExceptionPrecision();
|
||||
static bool getFpuExceptionUnderflow();
|
||||
static bool getFpuExceptionOverflow();
|
||||
static bool getFpuExceptionZeroDivide();
|
||||
static bool getFpuExceptionDenormal();
|
||||
static bool getFpuExceptionInvalid();
|
||||
|
||||
static bool getDemoMode();
|
||||
|
||||
static bool getUseRemoteDebug();
|
||||
static int getDefaultRemoteDebugPort();
|
||||
|
||||
static bool getProfilerExpandAllBranches();
|
||||
|
||||
static bool getMemoryManagerReportAllocations();
|
||||
static bool getMemoryManagerReportOnOutOfMemory();
|
||||
|
||||
static bool getUseMemoryBlockManager();
|
||||
static bool getMemoryBlockManagerDebugDumpOnRemove();
|
||||
|
||||
static int getFatalCallStackDepth();
|
||||
static int getWarningCallStackDepth();
|
||||
static bool getLookUpCallStackNames();
|
||||
|
||||
static bool getAlwaysCanSeeWorldCell();
|
||||
|
||||
static bool getVerboseWarnings();
|
||||
|
||||
static float getDebugReportLongFrameTime();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstPlatform.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef FIRST_PLATFORM_H
|
||||
#define FIRST_PLATFORM_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#define DLLEXPORT
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// C4514 unreferenced inline function has been removed
|
||||
// C4710 inline function not expanded
|
||||
// C4291 no matching operator delete found; memory will not be freed if initialization throws an exception
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "sharedFoundation/PlatformGlue.h"
|
||||
#include "sharedMemoryManager/MemoryManager.h"
|
||||
|
||||
|
||||
// ======================================================================
|
||||
|
||||
template <class T>
|
||||
inline int ComGetReferenceCount(T *t)
|
||||
{
|
||||
t->AddRef();
|
||||
return t->Release();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define FATAL_HR(a,b) FATAL(FAILED(b), (a, HRESULT_CODE(b)))
|
||||
#define DEBUG_FATAL_HR(a,b) DEBUG_FATAL(FAILED(b), (a, HRESULT_CODE(b)))
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,266 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FloatingPointUnit.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1999 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/FloatingPointUnit.h"
|
||||
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
int FloatingPointUnit::updateNumber;
|
||||
WORD FloatingPointUnit::status;
|
||||
FloatingPointUnit::Precision FloatingPointUnit::precision;
|
||||
FloatingPointUnit::Rounding FloatingPointUnit::rounding;
|
||||
bool FloatingPointUnit::exceptionEnabled[E_max];
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const WORD PRECISION_MASK = BINARY4(0000,0011,0000,0000);
|
||||
const WORD PRECISION_24 = BINARY4(0000,0000,0000,0000);
|
||||
const WORD PRECISION_53 = BINARY4(0000,0010,0000,0000);
|
||||
const WORD PRECISION_64 = BINARY4(0000,0011,0000,0000);
|
||||
|
||||
const WORD ROUND_MASK = BINARY4(0000,1100,0000,0000);
|
||||
const WORD ROUND_NEAREST = BINARY4(0000,0000,0000,0000);
|
||||
const WORD ROUND_CHOP = BINARY4(0000,1100,0000,0000);
|
||||
const WORD ROUND_DOWN = BINARY4(0000,0100,0000,0000);
|
||||
const WORD ROUND_UP = BINARY4(0000,1000,0000,0000);
|
||||
|
||||
const WORD EXCEPTION_PRECISION = BINARY4(0000,0000,0010,0000);
|
||||
const WORD EXCEPTION_UNDERFLOW = BINARY4(0000,0000,0001,0000);
|
||||
const WORD EXCEPTION_OVERFLOW = BINARY4(0000,0000,0000,1000);
|
||||
const WORD EXCEPTION_ZERO_DIVIDE = BINARY4(0000,0000,0000,0100);
|
||||
const WORD EXCEPTION_DENORMAL = BINARY4(0000,0000,0000,0010);
|
||||
const WORD EXCEPTION_INVALID = BINARY4(0000,0000,0000,0001);
|
||||
const WORD EXCEPTION_ALL = BINARY4(0000,0000,0011,1111);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void FloatingPointUnit::install(void)
|
||||
{
|
||||
precision = P_24;
|
||||
rounding = R_roundToNearestOrEven;
|
||||
memset(exceptionEnabled, 0, sizeof(exceptionEnabled));
|
||||
|
||||
// preserve all other bits
|
||||
status = getControlWord();
|
||||
status &= ~(PRECISION_MASK | ROUND_MASK | EXCEPTION_ALL);
|
||||
|
||||
// set to single precision, rounding, and all exceptions masked
|
||||
status |= PRECISION_24 | ROUND_NEAREST | EXCEPTION_ALL;
|
||||
|
||||
// check the config platform flags to see if we should enable some exceptions
|
||||
if (ConfigSharedFoundation::getFpuExceptionPrecision())
|
||||
{
|
||||
exceptionEnabled[E_precision] = true;
|
||||
status &= ~EXCEPTION_PRECISION;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionUnderflow())
|
||||
{
|
||||
exceptionEnabled[E_underflow] = true;
|
||||
status &= ~EXCEPTION_UNDERFLOW;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionOverflow())
|
||||
{
|
||||
exceptionEnabled[E_overflow] = true;
|
||||
status &= ~EXCEPTION_OVERFLOW;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionZeroDivide())
|
||||
{
|
||||
exceptionEnabled[E_zeroDivide] = true;
|
||||
status &= ~EXCEPTION_ZERO_DIVIDE;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionDenormal())
|
||||
{
|
||||
exceptionEnabled[E_denormal] = true;
|
||||
status &= ~EXCEPTION_DENORMAL;
|
||||
}
|
||||
|
||||
if (ConfigSharedFoundation::getFpuExceptionInvalid())
|
||||
{
|
||||
exceptionEnabled[E_invalid] = true;
|
||||
status &= ~EXCEPTION_INVALID;
|
||||
}
|
||||
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::update(void)
|
||||
{
|
||||
WORD currentStatus = getControlWord();
|
||||
|
||||
if (currentStatus != status)
|
||||
{
|
||||
DEBUG_REPORT_LOG_PRINT(true, ("FPU: update=%d, in mode=%04x, should be in mode=%04x", updateNumber, static_cast<int>(currentStatus), static_cast<int>(status)));
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
++updateNumber;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
WORD FloatingPointUnit::getControlWord(void)
|
||||
{
|
||||
//TODO wtf is this asm statement?
|
||||
#if 0
|
||||
WORD controlWord = 0;
|
||||
__asm fnstcw controlWord;
|
||||
return controlWord;
|
||||
#else
|
||||
return status;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setControlWord(WORD controlWord)
|
||||
{
|
||||
//TODO see above?
|
||||
|
||||
UNREF(controlWord);
|
||||
#if 0
|
||||
__asm fldcw controlWord;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setPrecision(Precision newPrecision)
|
||||
{
|
||||
WORD bits = 0;
|
||||
|
||||
switch (precision)
|
||||
{
|
||||
case P_24:
|
||||
bits = PRECISION_24;
|
||||
break;
|
||||
|
||||
case P_53:
|
||||
bits = PRECISION_53;
|
||||
break;
|
||||
|
||||
case P_64:
|
||||
bits = PRECISION_64;
|
||||
break;
|
||||
|
||||
case P_max:
|
||||
default:
|
||||
DEBUG_FATAL(true, ("bad case"));
|
||||
}
|
||||
|
||||
// record the current state
|
||||
precision = newPrecision;
|
||||
|
||||
// set the proper bit pattern
|
||||
status &= ~PRECISION_MASK;
|
||||
status |= bits;
|
||||
|
||||
// slam it into the FPU
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setRounding(Rounding newRounding)
|
||||
{
|
||||
WORD bits = 0;
|
||||
|
||||
switch (newRounding)
|
||||
{
|
||||
case R_roundToNearestOrEven:
|
||||
bits = ROUND_NEAREST;
|
||||
break;
|
||||
|
||||
case R_chop:
|
||||
bits = ROUND_CHOP;
|
||||
break;
|
||||
|
||||
case R_roundDown:
|
||||
bits = ROUND_DOWN;
|
||||
break;
|
||||
|
||||
case R_roundUp:
|
||||
bits = ROUND_UP;
|
||||
break;
|
||||
|
||||
case R_max:
|
||||
default:
|
||||
DEBUG_FATAL(true, ("bad case"));
|
||||
}
|
||||
|
||||
// record the current state
|
||||
rounding = newRounding;
|
||||
|
||||
// set the proper bit pattern
|
||||
status &= ~ROUND_MASK;
|
||||
status |= bits;
|
||||
|
||||
// slam it into the FPU
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FloatingPointUnit::setExceptionEnabled(Exception exception, bool enabled)
|
||||
{
|
||||
WORD bits = 0;
|
||||
|
||||
switch (exception)
|
||||
{
|
||||
case E_precision:
|
||||
bits = EXCEPTION_PRECISION;
|
||||
break;
|
||||
|
||||
case E_underflow:
|
||||
bits = EXCEPTION_UNDERFLOW;
|
||||
break;
|
||||
|
||||
case E_overflow:
|
||||
bits = EXCEPTION_OVERFLOW;
|
||||
break;
|
||||
|
||||
case E_zeroDivide:
|
||||
bits = EXCEPTION_ZERO_DIVIDE;
|
||||
break;
|
||||
|
||||
case E_denormal:
|
||||
bits = EXCEPTION_DENORMAL;
|
||||
break;
|
||||
|
||||
case E_invalid:
|
||||
bits = EXCEPTION_INVALID;
|
||||
break;
|
||||
|
||||
case E_max:
|
||||
default:
|
||||
DEBUG_FATAL(true, ("bad case"));
|
||||
}
|
||||
|
||||
// record the current state
|
||||
exceptionEnabled[exception] = enabled;
|
||||
|
||||
// twiddle the bit appropriately. these bits masks, so set the bit to disable the exception, clear the bit to enable it.
|
||||
if (enabled)
|
||||
status &= ~bits;
|
||||
else
|
||||
status |= bits;
|
||||
|
||||
// slam it into the FPU
|
||||
setControlWord(status);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,102 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FloatingPointUnit.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1999 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef FLOATING_POINT_UNIT_H
|
||||
#define FLOATING_POINT_UNIT_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class FloatingPointUnit
|
||||
{
|
||||
public:
|
||||
|
||||
enum Precision
|
||||
{
|
||||
P_24,
|
||||
P_53,
|
||||
P_64,
|
||||
|
||||
P_max
|
||||
};
|
||||
|
||||
enum Rounding
|
||||
{
|
||||
R_roundToNearestOrEven,
|
||||
R_chop,
|
||||
R_roundDown,
|
||||
R_roundUp,
|
||||
|
||||
R_max
|
||||
};
|
||||
|
||||
enum Exception
|
||||
{
|
||||
E_precision,
|
||||
E_underflow,
|
||||
E_overflow,
|
||||
E_zeroDivide,
|
||||
E_denormal,
|
||||
E_invalid,
|
||||
|
||||
E_max
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static int updateNumber;
|
||||
static WORD status;
|
||||
static Precision precision;
|
||||
static Rounding rounding;
|
||||
static bool exceptionEnabled[E_max];
|
||||
|
||||
public:
|
||||
|
||||
static WORD getControlWord(void);
|
||||
static void setControlWord(WORD controlWord);
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
|
||||
static void update(void);
|
||||
|
||||
static void setPrecision(Precision newPrecision);
|
||||
static void setRounding(Rounding newRounding);
|
||||
static void setExceptionEnabled(Exception exception, bool enabled);
|
||||
|
||||
static Precision getPrecision(void);
|
||||
static Rounding getRounding(void);
|
||||
static bool getExceptionEnabled(Exception exception);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline FloatingPointUnit::Precision FloatingPointUnit::getPrecision(void)
|
||||
{
|
||||
return precision;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline FloatingPointUnit::Rounding FloatingPointUnit::getRounding(void)
|
||||
{
|
||||
return rounding;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool FloatingPointUnit::getExceptionEnabled(Exception exception)
|
||||
{
|
||||
DEBUG_FATAL(static_cast<int>(exception) < 0 || static_cast<int>(exception) >= static_cast<int>(E_max), ("exception out of range")); //lint !e568 // non-negative quantity is never less than 0
|
||||
return exceptionEnabled[exception];
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,468 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Os.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
|
||||
#include "sharedFoundation/Clock.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedDebug/DebugMonitor.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/FloatingPointUnit.h"
|
||||
#include "sharedIoWin/IoWinManager.h"
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
bool Os::installed;
|
||||
bool Os::runInBackground;
|
||||
int Os::numberOfUpdates;
|
||||
int Os::menuValue;
|
||||
bool Os::paused;
|
||||
bool Os::wasPaused;
|
||||
bool Os::gameOver;
|
||||
bool Os::shouldReturnFromAbort;
|
||||
char Os::programName[PROGRAM_NAME_SIZE];
|
||||
char *Os::shortProgramName;
|
||||
pthread_t Os::mainThreadId;
|
||||
bool Os::threadDied;
|
||||
|
||||
bool Os::isMp;
|
||||
int Os::processorCount;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
namespace OsNamespace
|
||||
{
|
||||
class UncatchableException
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Install the Os subsystem for non-games.
|
||||
*
|
||||
* This routine is supported for all platforms, although different platforms may
|
||||
* require different arguments to this routine.
|
||||
*
|
||||
* This routine will add Os::remove to the ExitChain.
|
||||
*
|
||||
* @see Os::remove()
|
||||
*/
|
||||
|
||||
void Os::install(void)
|
||||
{
|
||||
installCommon();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* This routine will remove the Os subsystem.
|
||||
*
|
||||
* This routine should not be called directly. It will be called from the ExitChain.
|
||||
*
|
||||
* @see Os::install()
|
||||
*/
|
||||
|
||||
void Os::remove(void)
|
||||
{
|
||||
DEBUG_FATAL(!installed, ("not installed"));
|
||||
installed = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Os::installCommon(void)
|
||||
{
|
||||
DEBUG_FATAL(installed, ("already installed"));
|
||||
|
||||
ExitChain::add(Os::remove, "Os::remove", 0, true);
|
||||
|
||||
#if 0 //TODO For now we won't screw with the priority of the process
|
||||
HANDLE threadHandle = GetCurrentThread();
|
||||
DEBUG_FATAL(!SetThreadPriority(threadHandle, THREAD_PRIORITY_ABOVE_NORMAL), ("Failed to set game thread priority"));
|
||||
#endif
|
||||
|
||||
numberOfUpdates = 0;
|
||||
mainThreadId = pthread_self();
|
||||
|
||||
// get the name of the executable
|
||||
//Can't find UNIX call for this: DWORD result = GetModuleFileName(NULL, programName, sizeof(programName));
|
||||
strcpy(programName, "TempName");
|
||||
DWORD result = 1;
|
||||
|
||||
|
||||
FATAL(result == 0, ("GetModuleFileName failed"));
|
||||
|
||||
// get the file name without the path
|
||||
shortProgramName = strrchr(programName, '\\');
|
||||
if (shortProgramName)
|
||||
++shortProgramName;
|
||||
else
|
||||
shortProgramName = programName;
|
||||
|
||||
// determine the number of processors by parsing /proc/cpuinfo
|
||||
processorCount = 1;
|
||||
FILE * f = fopen("/proc/cpuinfo", "r");
|
||||
if (f)
|
||||
{
|
||||
char buffer[512];
|
||||
while (!feof(f))
|
||||
{
|
||||
fgets(buffer, 512, f);
|
||||
if (strncmp(buffer, "processor\t: ", 12)==0)
|
||||
{
|
||||
processorCount = atoi(buffer+12)+1;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
isMp = processorCount > 1;
|
||||
|
||||
// switch into single-precision floating point mode
|
||||
FloatingPointUnit::install();
|
||||
|
||||
installed = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::isMainThread(void)
|
||||
{
|
||||
// if the Os class hasn't been installed, then assume we are the main thread.
|
||||
// otherwise, check to see if our thread id is the main thread id
|
||||
return !installed || (pthread_self() == mainThreadId);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Terminate the application because of an error condition.
|
||||
*
|
||||
* This routine is supported for all platforms.
|
||||
*
|
||||
* This routine should not be called directly. The engine and game should use the
|
||||
* FATAL macro to terminate the application because of an error.
|
||||
*
|
||||
* Calling Os::returnFromAbort() will cause the routine to do nothing but return
|
||||
* immediately.
|
||||
*
|
||||
* @see Os::returnFromAbort(), FATAL()
|
||||
*/
|
||||
#include <signal.h>
|
||||
void Os::abort(void)
|
||||
{
|
||||
if (!isMainThread())
|
||||
{
|
||||
threadDied = true;
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
if (!shouldReturnFromAbort)
|
||||
{
|
||||
// let the C runtime deal with the abnormal termination
|
||||
int * dummy = NULL;
|
||||
int forceCrash = *dummy;
|
||||
UNREF(forceCrash);
|
||||
for (;;)
|
||||
{
|
||||
// One of these should work:
|
||||
pthread_kill(pthread_self(), SIGSEGV);
|
||||
::kill(0,SIGSEGV);
|
||||
::abort();
|
||||
OsNamespace::UncatchableException ex;
|
||||
throw ex;
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Create the specified directory and all of it's parents.
|
||||
* @param directory the path to a directory
|
||||
* @return always true currently
|
||||
*/
|
||||
|
||||
bool Os::createDirectories (const char *directory)
|
||||
{
|
||||
//-- construct list of subdirectories all the way down to root
|
||||
std::stack<std::string> directoryStack;
|
||||
|
||||
std::string currentDirectory = directory;
|
||||
|
||||
static const char path_seps [] = { '\\', '/', 0 };
|
||||
|
||||
// build the stack
|
||||
while (!currentDirectory.empty())
|
||||
{
|
||||
// remove trailing backslash
|
||||
if (currentDirectory[currentDirectory.size()-1] == '\\' || currentDirectory[currentDirectory.size()-1] == '/')
|
||||
IGNORE_RETURN(currentDirectory.erase(currentDirectory.size()-1));
|
||||
|
||||
if (currentDirectory[currentDirectory.size()-1] == ':')
|
||||
{
|
||||
// we've hit something like c:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!currentDirectory.empty())
|
||||
directoryStack.push(currentDirectory);
|
||||
|
||||
// now strip off current directory
|
||||
size_t previousDirIndex = currentDirectory.find_last_of (path_seps);
|
||||
if (previousDirIndex == currentDirectory.npos)
|
||||
break;
|
||||
else
|
||||
IGNORE_RETURN(currentDirectory.erase(previousDirIndex));
|
||||
}
|
||||
|
||||
//-- build all directories specified by the initial directory
|
||||
while (!directoryStack.empty())
|
||||
{
|
||||
// get the directory
|
||||
currentDirectory = directoryStack.top();
|
||||
directoryStack.pop();
|
||||
|
||||
// try to create it (don't pass any security attributes)
|
||||
IGNORE_RETURN (mkdir (currentDirectory.c_str(), 0));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Write out a file.
|
||||
*
|
||||
* The file name and where the file is written is system-dependent.
|
||||
*
|
||||
* @param fileName Name of the file to write
|
||||
* @param data Data buffer to write to the file
|
||||
*/
|
||||
|
||||
bool Os::writeFile(const char *fileName, const void *data, int length) // Length of the data bufferto write
|
||||
{
|
||||
BOOL result;
|
||||
HANDLE handle;
|
||||
DWORD written;
|
||||
|
||||
// open the file for writing
|
||||
handle = CreateFile(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
// check if it was opened
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
// attempt to write the data
|
||||
result = WriteFile(handle, data, static_cast<DWORD>(length), &written, NULL);
|
||||
|
||||
// make sure the data was written okay
|
||||
if (!result || written != static_cast<DWORD>(length))
|
||||
{
|
||||
static_cast<void>(CloseHandle(handle));
|
||||
return false;
|
||||
}
|
||||
|
||||
// close the file
|
||||
result = CloseHandle(handle);
|
||||
|
||||
// make sure the close was sucessful
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Update the Os subsystem.
|
||||
*
|
||||
* This routine is supported for all platforms.
|
||||
*
|
||||
* For the Win* platforms, this routine will process the windows message pump.
|
||||
*/
|
||||
|
||||
bool Os::update(void)
|
||||
{
|
||||
static int ppid = getppid();
|
||||
|
||||
FloatingPointUnit::update();
|
||||
|
||||
++numberOfUpdates;
|
||||
|
||||
#if 0
|
||||
#ifdef _DEBUG
|
||||
|
||||
if (DEBUG_FLAG_PLATFORM(validateHeap))
|
||||
{
|
||||
PROFILER_START("validate heap");
|
||||
MemoryManager::validate();
|
||||
PROFILER_STOP("validate heap");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Clock::update();
|
||||
|
||||
wasPaused = false;
|
||||
|
||||
// if our parent's pid has changed, we tell our caller it should exit
|
||||
if (getppid() != ppid)
|
||||
{
|
||||
WARNING(true, ("Parent process exited!"));
|
||||
// reset the parent process id, so we don't keep spamming warnings for processes that don't exit because of this
|
||||
ppid = getppid();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Formats a message error using GetLastError() and FormatMessge().
|
||||
*
|
||||
* The buffer returned from this function is dynamically allocated to prevent
|
||||
* issues with this routine being called from multiple threads. The caller
|
||||
* must delete the buffer when it is done.
|
||||
*
|
||||
* @return A dynamically allocated buffer containing the error message
|
||||
*/
|
||||
|
||||
char *Os::getLastError(void)
|
||||
{
|
||||
return DuplicateString(strerror(errno));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::getAbsolutePath(const char *relativePath, char *absolutePath, int absolutePathBufferSize)
|
||||
{
|
||||
// realpath sucks and could cause a buffer overrun. however, it's better than writing it ourselves for now.
|
||||
char *result = realpath(relativePath, absolutePath);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
FATAL(istrlen(absolutePath)+1 > absolutePathBufferSize, ("buffer overrun"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the actual system time, in seconds since the epoch.
|
||||
*
|
||||
* Do not use this for most game systems, since it does not take into account
|
||||
* clock sku, game loop times, etc.
|
||||
*/
|
||||
time_t Os::getRealSystemTime(void)
|
||||
{
|
||||
return time(0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert a time in seconds since the epoch to GMT.
|
||||
*
|
||||
*/
|
||||
|
||||
void Os::convertTimeToGMT(const time_t &time, tm &zulu)
|
||||
{
|
||||
zulu=*gmtime(&time); // gmtime uses a single static tm structure. Yuck!
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert a tm structure to the time in seconds since the epoch.
|
||||
*
|
||||
*/
|
||||
|
||||
time_t Os::convertGMTToTime(const tm &zulu)
|
||||
{
|
||||
return mktime(const_cast<tm*>(&zulu));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get a unique identifier for this thread.
|
||||
*
|
||||
* @return A unique identifier for this thread.
|
||||
*/
|
||||
|
||||
Os::ThreadId Os::getThreadId()
|
||||
{
|
||||
return pthread_self();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Assign the given thread a reasonable name (only works for MSDev 6.0 debugger)
|
||||
* Since this is Linux-specific, make sure this fuction does nothing
|
||||
*
|
||||
*/
|
||||
|
||||
void Os::setThreadName(DWORD threadID, const char* threadName)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Cause the current thread to sleep for a period of time. If the period is
|
||||
* zero, the current thread yields it's timeslice.
|
||||
*/
|
||||
|
||||
void Os::sleep(int ms)
|
||||
{
|
||||
if (ms == 0)
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Copy text to the system clipboard.
|
||||
*
|
||||
* This routine can be used if the application wants to make some data easily available for pasting (like crash call stacks).
|
||||
*/
|
||||
|
||||
bool Os::copyTextToClipboard(const char *text)
|
||||
{
|
||||
UNREF(text);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Os::OsPID_t Os::getProcessId()
|
||||
{
|
||||
return getpid();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Os::setProgramName(const char * name)
|
||||
{
|
||||
strncpy(programName, name, Os::PROGRAM_NAME_SIZE);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Os::isFocused()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -0,0 +1,264 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Os.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef OS_H
|
||||
#define OS_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
struct DebugMenuEntry;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Os
|
||||
{
|
||||
public:
|
||||
|
||||
typedef pthread_t ThreadId;
|
||||
typedef pid_t OsPID_t;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_PATH_LENGTH = 512
|
||||
};
|
||||
|
||||
typedef void (*QueueCharacterHookFunction)(int keyboard, int character);
|
||||
typedef void (*SetSystemMouseCursorPositionHookFunction)(int x, int y);
|
||||
typedef void (*QueueKeyDownHookFunction)(int keyboard, int character);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Os(void);
|
||||
Os(const Os &);
|
||||
Os &operator =(const Os &);
|
||||
|
||||
enum
|
||||
{
|
||||
PROGRAM_NAME_SIZE = 512
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static void remove(void);
|
||||
|
||||
static void installCommon(void);
|
||||
|
||||
private:
|
||||
|
||||
static bool installed;
|
||||
static bool runInBackground;
|
||||
static int numberOfUpdates;
|
||||
static int menuValue;
|
||||
static DebugMenuEntry *debugMenuGame;
|
||||
static bool paused;
|
||||
static bool wasPaused;
|
||||
static bool gameOver;
|
||||
static bool shouldReturnFromAbort;
|
||||
static bool wantPopupDebugMenu;
|
||||
static char programName[PROGRAM_NAME_SIZE];
|
||||
static char *shortProgramName;
|
||||
static pthread_t mainThreadId;
|
||||
static bool threadDied;
|
||||
static bool isMp;
|
||||
static int processorCount;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
|
||||
static bool isGameOver(void);
|
||||
static bool isMainThread(void);
|
||||
static bool wasApplicationPaused(void);
|
||||
|
||||
static bool update(void);
|
||||
|
||||
static void returnFromAbort(void);
|
||||
static void abort(void);
|
||||
|
||||
static void requestPopupDebugMenu();
|
||||
|
||||
static bool createDirectories (const char *dirname);
|
||||
|
||||
static bool writeFile(const char *fileName, const void *data, int length);
|
||||
|
||||
static int getNumberOfUpdates(void);
|
||||
|
||||
static char *getLastError(void);
|
||||
|
||||
static void setThreadName(DWORD threadID, const char* name);
|
||||
static ThreadId getThreadId();
|
||||
|
||||
static const char *getProgramName(void);
|
||||
static const char *getShortProgramName(void);
|
||||
static void setProgramName(const char * name);
|
||||
|
||||
static bool getAbsolutePath(const char *relativePath, char *absolutePath, int absolutePathBufferSize);
|
||||
|
||||
static void sleep(int ms);
|
||||
|
||||
static time_t getRealSystemTime(void);
|
||||
static void convertTimeToGMT(const time_t &time, tm &zulu);
|
||||
static time_t convertGMTToTime(const tm &zulu);
|
||||
|
||||
static bool isMultiprocessor();
|
||||
static int getProcessorCount();
|
||||
|
||||
static bool copyTextToClipboard(const char *text);
|
||||
|
||||
static bool wasFocusLost();
|
||||
static void setQueueCharacterHookFunction(QueueCharacterHookFunction queueCharacterHookFunction);
|
||||
static void setSetSystemMouseCursorPositionHookFunction(SetSystemMouseCursorPositionHookFunction setSystemMouseCursorPositionHookFunction);
|
||||
static OsPID_t getProcessId();
|
||||
static bool isFocused();
|
||||
|
||||
static void setQueueKeyDownHookFunction(QueueKeyDownHookFunction queueKeyDownHookFunction);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the full name of the running executable.
|
||||
*
|
||||
* The program name will include the path as well.
|
||||
*
|
||||
* @return The full name of the running executable
|
||||
* @see Os::getShortProgramName()
|
||||
*/
|
||||
|
||||
inline const char *Os::getProgramName(void)
|
||||
{
|
||||
return programName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the short name of the running executable.
|
||||
*
|
||||
* The program name will not include the path, but will just be the file name.
|
||||
*
|
||||
* @return The short name of the running executable
|
||||
* @see Os::getProgramName()
|
||||
*/
|
||||
|
||||
inline const char *Os::getShortProgramName(void)
|
||||
{
|
||||
return shortProgramName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Cause Os::abort() to return instead of abort the process.
|
||||
*
|
||||
* This routine should not be called directly by users.
|
||||
*
|
||||
* This routine is provided so that structured exception handling can catch
|
||||
* an exception, call Fatal to run the ExitChain, and rethrow the exception
|
||||
* so that the debugger will catch it.
|
||||
*/
|
||||
|
||||
inline void Os::returnFromAbort(void)
|
||||
{
|
||||
shouldReturnFromAbort = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Check if the Os knows the game needs to shut down.
|
||||
*
|
||||
* The Os can decide that the game need to end for a number of reasons,
|
||||
* including closing the application or shutting the machine down.
|
||||
*
|
||||
* @return True if the game should quit, otherwise false
|
||||
*/
|
||||
|
||||
inline bool Os::isGameOver(void)
|
||||
{
|
||||
return gameOver;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the number of updates that the have occurred.
|
||||
*
|
||||
* @return This value is updated during the Os::update() routine.
|
||||
*/
|
||||
|
||||
inline int Os::getNumberOfUpdates(void)
|
||||
{
|
||||
return numberOfUpdates;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Indicate whether or not the application was paused.
|
||||
*
|
||||
* @return True if the application was in the background (paused), otherwise false
|
||||
*/
|
||||
|
||||
inline bool Os::wasApplicationPaused(void)
|
||||
{
|
||||
return wasPaused;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return a flag indicating whether we are running a multiprocessor machine or not.
|
||||
*
|
||||
* @return True if the machine has more than one processor, false if not.
|
||||
*/
|
||||
|
||||
inline bool Os::isMultiprocessor(void)
|
||||
{
|
||||
return isMp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the number of processors.
|
||||
*
|
||||
* @return The number of processors in the machine.
|
||||
*/
|
||||
|
||||
inline int Os::getProcessorCount(void)
|
||||
{
|
||||
return processorCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool Os::wasFocusLost()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void Os::setQueueCharacterHookFunction(QueueCharacterHookFunction queueCharacterHookFunction)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void Os::setSetSystemMouseCursorPositionHookFunction(SetSystemMouseCursorPositionHookFunction setSystemMouseCursorPositionHookFunction)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void Os::setQueueKeyDownHookFunction(QueueKeyDownHookFunction)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,161 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PerThreadData.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
|
||||
#include "sharedSynchronization/Gate.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
pthread_key_t PerThreadData::slot;
|
||||
bool PerThreadData::slotCreated=false;
|
||||
|
||||
// ======================================================================
|
||||
// Install the per-thread-data subsystem
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine will install the per-thread-data subsystem that is required for several
|
||||
// other subsystems in the engine. It should be called from the primary thread before
|
||||
// any other threads have been created. It will also call threadInstall() for the
|
||||
// primary thread.
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// PerThreadData::remove()
|
||||
|
||||
void PerThreadData::install(void)
|
||||
{
|
||||
if (pthread_key_create(&slot, 0)!=0)
|
||||
{
|
||||
FATAL(true, ("pthread_key_create failed"));
|
||||
}
|
||||
slotCreated=true;
|
||||
|
||||
threadInstall();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Remove the per-thread-subsystem.
|
||||
*
|
||||
* This routine should be called by the primary thread after all other threads have
|
||||
* terminated, and no other uses of per-thread-data will occur.
|
||||
*
|
||||
* @see PerThreadData::install()
|
||||
*/
|
||||
|
||||
void PerThreadData::remove(void)
|
||||
{
|
||||
threadRemove();
|
||||
|
||||
if (pthread_key_delete(slot)!=0)
|
||||
{
|
||||
FATAL(true, ("pthread_key_delete failed"));
|
||||
}
|
||||
|
||||
slotCreated=false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get access to the per-thread-data.
|
||||
*
|
||||
* This routine will verify the per-thread-data subsystem has been installed and the
|
||||
* threadInstall() function has been called for the current thread.
|
||||
*
|
||||
* @return A pointer to the per-thread-data.
|
||||
*/
|
||||
|
||||
PerThreadData::Data *PerThreadData::getData(bool allowReturnNull)
|
||||
{
|
||||
UNREF(allowReturnNull);
|
||||
|
||||
if (!slotCreated)
|
||||
{
|
||||
DEBUG_FATAL(true && !allowReturnNull, ("not installed"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Data * const data = reinterpret_cast<Data *>(pthread_getspecific(slot));
|
||||
DEBUG_FATAL(!data && !allowReturnNull, ("not installed for this thread"));
|
||||
return data;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Create the per-thread-data for a new thread.
|
||||
*
|
||||
* This routine should be called in a thread before the first usage of per-thread-data.
|
||||
*
|
||||
* If the client is calling this function on a thread that existed before the engine was
|
||||
* installed, the client should set isNewThread to false. Setting isNewThread to false
|
||||
* prevents the function from validating that the thread's TLS is NULL. For threads existing
|
||||
* before the engine is installed, the TLS data for the thread is undefined.
|
||||
*
|
||||
* @param isNewThread [IN] true if the thread was created after the engine was installed, false otherwise
|
||||
* @see PerThreadData::threadRemove()
|
||||
*/
|
||||
|
||||
void PerThreadData::threadInstall(bool isNewThread)
|
||||
{
|
||||
UNREF(isNewThread);
|
||||
|
||||
DEBUG_FATAL(!slotCreated, ("not installed"));
|
||||
|
||||
// only check for already-set data if this is supposed to be a new thread
|
||||
DEBUG_FATAL(isNewThread && pthread_getspecific(slot), ("already installed for this thread"));
|
||||
|
||||
// create the data
|
||||
Data * const data = new Data;
|
||||
|
||||
// initialize the data
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
//create the event for file streaming reads
|
||||
data->readGate = new Gate(false);
|
||||
|
||||
// set the data into the thread slot
|
||||
const BOOL result = pthread_setspecific(slot, data);
|
||||
UNREF(result);
|
||||
DEBUG_FATAL(result, ("pthread_setspecific failed")); //NB: unlike Windows, returns 0 on success.
|
||||
} //lint !e429 // Warning -- Custodial pointer 'data' has not been freed or returned) // stored int thread-local-storage
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Destroythe per-thread-data for a terminating thread.
|
||||
*
|
||||
* This routine should be called in a thread after the last usage of per-thread-data.
|
||||
*
|
||||
* @see PerThreadData::threadInstall()
|
||||
*/
|
||||
|
||||
void PerThreadData::threadRemove(void)
|
||||
{
|
||||
DEBUG_FATAL(!slotCreated, ("not installed"));
|
||||
DEBUG_FATAL(!pthread_getspecific(slot), ("thread not installed"));
|
||||
|
||||
// get the data
|
||||
Data *data = getData();
|
||||
|
||||
//close the event used for file streaming reads
|
||||
delete data->readGate;
|
||||
data->readGate = NULL;
|
||||
|
||||
// wipe the data in the thread slot
|
||||
const BOOL result2 = pthread_setspecific(slot, NULL);
|
||||
UNREF(result2);
|
||||
DEBUG_FATAL(result2, ("TlsSetValue failed")); //NB: unlike Windows, returns 0 on success.
|
||||
|
||||
// free the memory
|
||||
delete data;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,232 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PerThreadData.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef PER_THREAD_DATA_H
|
||||
#define PER_THREAD_DATA_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
|
||||
class Gate;
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Provide thread local storage functionality.
|
||||
*
|
||||
* This class' purpose is to allow each thread to maintain some storage that is local and private to each thread.
|
||||
* The system must be installed before use. Each thread that may use per-thread-data will also need to call the
|
||||
* threadInstall() routine after creation and threadRemove() just before termination of the thread.
|
||||
*/
|
||||
class PerThreadData
|
||||
{
|
||||
private:
|
||||
|
||||
struct Data
|
||||
{
|
||||
bool exitChainRunning;
|
||||
bool exitChainFataling;
|
||||
ExitChain::Entry *exitChainFirstEntry;
|
||||
|
||||
int debugPrintFlags;
|
||||
|
||||
Gate *readGate;
|
||||
};
|
||||
|
||||
static pthread_key_t slot;
|
||||
static bool slotCreated;
|
||||
|
||||
private:
|
||||
|
||||
static Data *getData(bool allowReturnNull=false);
|
||||
|
||||
private:
|
||||
|
||||
PerThreadData(void);
|
||||
PerThreadData(const PerThreadData &);
|
||||
PerThreadData &operator =(const PerThreadData &);
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
static void remove(void);
|
||||
|
||||
static void threadInstall(bool isNewThread = true);
|
||||
static void threadRemove(void);
|
||||
|
||||
static bool isThreadInstalled(void);
|
||||
|
||||
static bool getExitChainRunning(void);
|
||||
static void setExitChainRunning(bool newValue);
|
||||
|
||||
static bool getExitChainFataling(void);
|
||||
static void setExitChainFataling(bool newValue);
|
||||
|
||||
static ExitChain::Entry *getExitChainFirstEntry(void);
|
||||
static void setExitChainFirstEntry(ExitChain::Entry *newValue);
|
||||
|
||||
static int getDebugPrintFlags(void);
|
||||
static void setDebugPrintFlags(int newValue);
|
||||
|
||||
static Gate *getFileStreamerReadGate(void);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Determine if the per-thread-data is available for this thread
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* True if the per-thread-data is installed correctly, false otherwise
|
||||
*
|
||||
* Remarks:
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* -TRF- looks like Win98 does not zero out a new TLS slot for
|
||||
* threads existing at the time of slot creation. Thus, if you build a
|
||||
* plugin that only initializes the engine the first time it is
|
||||
* used, and other threads already exist in the app, those threads
|
||||
* will contain bogus non-null data in the TLS slot. If the plugin really
|
||||
* wants to do lazy initialization of the engine, it will need
|
||||
* to handle calling PerThreadData::threadInstall() for all existing threads
|
||||
* (except the thread that initialized the engine, which already
|
||||
* has its PerThreadData::threadInstall() called).
|
||||
*/
|
||||
|
||||
inline bool PerThreadData::isThreadInstalled(void)
|
||||
{
|
||||
return (getData(true) != NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the exit chain running flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @return True if the exit chain is running, false otherwise.
|
||||
* @see ExitChain::isRunning()
|
||||
*/
|
||||
|
||||
inline bool PerThreadData::getExitChainRunning(void)
|
||||
{
|
||||
return getData()->exitChainRunning;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the exit chain running flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @param newValue New value for the exit chain running flag
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setExitChainRunning(bool newValue)
|
||||
{
|
||||
getData()->exitChainRunning = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the exit chain fataling flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @return True if the exit chain is fataling, false otherwise.
|
||||
* @see ExitChain::isFataling()
|
||||
*/
|
||||
|
||||
inline bool PerThreadData::getExitChainFataling(void)
|
||||
{
|
||||
return getData()->exitChainFataling;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the exit chain fataling flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
*
|
||||
* @param newValue New value for the exit chain fataling flag
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setExitChainFataling(bool newValue)
|
||||
{
|
||||
getData()->exitChainFataling = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the first entry for the exit chain.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
* This routine may return NULL.
|
||||
*
|
||||
* @return Pointer to the first entry on the exit chain
|
||||
* @see ExitChain::isFataling()
|
||||
*/
|
||||
|
||||
inline ExitChain::Entry *PerThreadData::getExitChainFirstEntry(void)
|
||||
{
|
||||
return getData()->exitChainFirstEntry;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the exit chain fataling flag value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the ExitChain class.
|
||||
* The parameter to this routine may be NULL.
|
||||
*
|
||||
* @param newValue New value for the exit chain first entry
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setExitChainFirstEntry(ExitChain::Entry *newValue)
|
||||
{
|
||||
getData()->exitChainFirstEntry = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get the debug print flags.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the DebugPrint functions.
|
||||
*
|
||||
* @return Current value of the debug print flags
|
||||
*/
|
||||
|
||||
inline int PerThreadData::getDebugPrintFlags(void)
|
||||
{
|
||||
return getData()->debugPrintFlags;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the debug print flags value.
|
||||
*
|
||||
* This routine is not intended for general use; it should only be used by the DebugPrint functions.
|
||||
*/
|
||||
|
||||
inline void PerThreadData::setDebugPrintFlags(int newValue)
|
||||
{
|
||||
getData()->debugPrintFlags = newValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline Gate *PerThreadData::getFileStreamerReadGate(void)
|
||||
{
|
||||
return getData()->readGate;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,273 @@
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/PlatformGlue.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
real abs(real x)
|
||||
{
|
||||
return fabs(x);
|
||||
}
|
||||
|
||||
int _stricmp(const char* string1, const char* string2)
|
||||
{
|
||||
int first, second;
|
||||
|
||||
do
|
||||
{
|
||||
first = toupper(*string1);
|
||||
second = toupper(*string2);
|
||||
string1++;
|
||||
string2++;
|
||||
} while (first && first==second);
|
||||
|
||||
return (first - second);
|
||||
}
|
||||
|
||||
char* _itoa(int value, char* stringOut, int radix)
|
||||
{
|
||||
DEBUG_FATAL((radix != 10), ("itoa only supprts base 10"));
|
||||
sprintf(stringOut, "%d", value);
|
||||
return stringOut;
|
||||
}
|
||||
|
||||
bool QueryPerformanceCounter(__int64* time)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
*time = static_cast<LARGE_INTEGER>(tv.tv_sec);
|
||||
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(tv.tv_usec);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool QueryPerformanceFrequency(__int64 *freq)
|
||||
{
|
||||
*freq = CLOCKS_PER_SEC;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
void Sleep(DWORD msecs)
|
||||
{
|
||||
//Sleep takes a time to sleep in milliseconds.
|
||||
usleep(msecs*1000); //usleep works with microseconds
|
||||
}
|
||||
|
||||
int GetLastError()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
void OutputDebugString(const char* stringOut)
|
||||
{
|
||||
fprintf(stderr,"%s",stringOut);
|
||||
}
|
||||
|
||||
|
||||
//File Support
|
||||
BOOL WriteFile(FILE* hFile, const void* lpBuffer, DWORD numBytesToWrite, DWORD* numBytesWritten, void* unsup)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if(unsup)
|
||||
return FALSE; //Windows doesn't support this overrlap buffer
|
||||
|
||||
retval = fwrite(lpBuffer, sizeof(char), numBytesToWrite, hFile);
|
||||
*numBytesWritten = retval;
|
||||
return (retval < 0) ? FALSE : TRUE;
|
||||
|
||||
}
|
||||
|
||||
BOOL ReadFile(FILE* hFile, void* lpBuffer, DWORD numBytesToRead, DWORD* numBytesRead, void* unsup)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if(unsup)
|
||||
return FALSE; //Windows doesn't support this overrlap buffer
|
||||
|
||||
retval = fread(lpBuffer, sizeof(char), numBytesToRead, hFile);
|
||||
*numBytesRead = retval;
|
||||
return (retval <= 0) ? FALSE : TRUE;
|
||||
|
||||
}
|
||||
|
||||
DWORD SetFilePointer(FILE* hFile, long lDistanceToMove, long* lpDistanceToMoveHigh, DWORD dwMoveMethod)
|
||||
{
|
||||
//Mimics the Win32 function to set the position of a file pointer. return -1 on failure else current position.
|
||||
|
||||
int retval;
|
||||
retval = fseek(hFile, lDistanceToMove, dwMoveMethod);
|
||||
|
||||
return (retval == 0) ? ftell(hFile) : -1;
|
||||
}
|
||||
|
||||
//TODO Consider using a call to open() instead of fopen() to get a better mapping of parameters to Win32
|
||||
FILE* CreateFile(const char* fileName, DWORD access, DWORD shareMode, void* unsupA, DWORD creationDisposition, DWORD flagsAndAttributes, FILE* unsupB)
|
||||
{
|
||||
FILE* retval = 0;
|
||||
|
||||
DEBUG_FATAL(flagsAndAttributes != FILE_ATTRIBUTE_NORMAL, ("Unsupported File mode call to CreateFile()"));
|
||||
DEBUG_FATAL(unsupB != NULL, ("Unsupported File mode call to CreateFile()"));
|
||||
//DEBUG_FATAL(shareMode != 0, ("Unsupported File mode call to CreateFile()"));
|
||||
DEBUG_FATAL(unsupA != 0, ("Unsupported File mode call to CreateFile()"));
|
||||
|
||||
switch(creationDisposition)
|
||||
{
|
||||
case CREATE_NEW:
|
||||
retval = fopen(fileName, "r");
|
||||
if (retval)
|
||||
{
|
||||
fclose(retval);
|
||||
retval = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(retval);
|
||||
retval = fopen(fileName, "w");
|
||||
}
|
||||
break;
|
||||
|
||||
case CREATE_ALWAYS:
|
||||
retval = fopen(fileName, "w");
|
||||
break;
|
||||
|
||||
case OPEN_EXISTING:
|
||||
retval = fopen(fileName, "r");
|
||||
if ((access & GENERIC_WRITE) && retval)
|
||||
{
|
||||
fclose(retval);
|
||||
retval = fopen(fileName, "a");
|
||||
rewind(retval);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPEN_ALWAYS:
|
||||
if (access & GENERIC_WRITE)
|
||||
{
|
||||
retval = fopen(fileName, "a");
|
||||
rewind(retval);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = fopen(fileName, "r");
|
||||
}
|
||||
break;
|
||||
|
||||
case TRUNCATE_EXISTING:
|
||||
DEBUG_FATAL(!(access & GENERIC_WRITE),("Must open truncate file with write access"));
|
||||
retval = fopen(fileName, "w");
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
BOOL CloseHandle(FILE* hFile)
|
||||
{
|
||||
int retval = fclose(hFile);
|
||||
return (retval == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
//TODO There must be a more elegant UNIX command to get file size...fstat() needs filename
|
||||
DWORD GetFileSize(FILE* hFile, DWORD* lpHighSize)
|
||||
{
|
||||
long int curPos;
|
||||
DWORD endPos;
|
||||
curPos = ftell(hFile);
|
||||
fseek(hFile, 0, SEEK_END);
|
||||
endPos = ftell(hFile);
|
||||
fseek(hFile, curPos, SEEK_SET);
|
||||
return endPos;
|
||||
|
||||
#if 0
|
||||
//This is what I want to do, but I have no file des number
|
||||
struct stat buf;
|
||||
fstat(hFile, &buf);
|
||||
return buf->st_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL FileExists(const char* filename)
|
||||
{
|
||||
BOOL retval = false;
|
||||
|
||||
struct stat info;
|
||||
if (stat(filename, &info) == 0)
|
||||
{
|
||||
if (S_ISREG(info.st_mode))
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Memory Functions
|
||||
|
||||
void* VirtualAlloc(void* location, DWORD size, DWORD flAllocationType, DWORD flProtect)
|
||||
{
|
||||
if (location)
|
||||
return location;
|
||||
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
BOOL VirtualFree(void* location, DWORD size, DWORD freeType)
|
||||
{
|
||||
free(location);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL VirtualProtect(void* location, DWORD size, DWORD newProtect, DWORD* oldProect)
|
||||
{
|
||||
//Unused. Function stub for compatibility
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL IsBadReadPtr(const void* location, unsigned int size)
|
||||
{
|
||||
//unused
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void MessageBox (void* unused, const char* message, const char* unused2, int flags)
|
||||
{
|
||||
OutputDebugString(message);
|
||||
}
|
||||
|
||||
char *ConvertCommandLine(int argc, char ** argv)
|
||||
{
|
||||
static char buffer[2048];
|
||||
|
||||
int totalSize=0;
|
||||
for (int i=0; i<argc; ++i)
|
||||
{
|
||||
totalSize+=strlen(argv[i])+1;
|
||||
}
|
||||
|
||||
if(totalSize>1023)
|
||||
{
|
||||
int argIndex = 0;
|
||||
fprintf(stderr, "Exceeded command line args length of %d. Total size is %d\n", sizeof(buffer), totalSize);
|
||||
for(argIndex = 0; argIndex < argc; ++argIndex)
|
||||
{
|
||||
fprintf(stderr, "argv[%d]=\"%s\"\n", argIndex, argv[argIndex]);
|
||||
}
|
||||
FATAL(true,("Command line exceeds maximum length."));
|
||||
}
|
||||
|
||||
buffer[0]='\0';
|
||||
|
||||
for (int i=0; i<argc; ++i)
|
||||
{
|
||||
strcat(buffer,argv[i]);
|
||||
if (i!=argc-1)
|
||||
{
|
||||
strcat(buffer," ");
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
#ifndef INCLUDED_MISC_H
|
||||
#define INCLUDED_MISC_H
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef unsigned short int WORD;
|
||||
typedef unsigned long int DWORD;
|
||||
typedef bool BOOL;
|
||||
typedef long long __int64; //lint !e13 !e19 // Error: 13 (Bad type), Error: 19 (Useless declaration) // -TRF- Lint preprocessor discrepency, @todo look into this.
|
||||
typedef __int64 LARGE_INTEGER;
|
||||
|
||||
const BOOL FALSE = 0;
|
||||
const BOOL TRUE = 1;
|
||||
|
||||
|
||||
float abs(float x);
|
||||
int _stricmp(const char* string1, const char* string2);
|
||||
|
||||
//String to numeric conversions
|
||||
char* _itoa(int value, char* stringOut, int radix);
|
||||
|
||||
//Format specifier for non-portable printf
|
||||
#define UINT64_FORMAT_SPECIFIER "%llu"
|
||||
#define INT64_FORMAT_SPECIFIER "%lli"
|
||||
|
||||
//Constant definition macro for 64 bit values
|
||||
#define UINT64_LITERAL(a) a ## ull
|
||||
#define INT64_LITERAL(a) a ## ll
|
||||
|
||||
bool QueryPerformanceCounter(__int64 *time);
|
||||
bool QueryPerformanceFrequency(__int64 *freq);
|
||||
void Sleep(DWORD msecs);
|
||||
int GetLastError();
|
||||
void OutputDebugString(const char* stringOut);
|
||||
|
||||
//File Support
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef FILE* HANDLE;
|
||||
|
||||
#define INVALID_HANDLE_VALUE NULL //Have to use a #define because this may be a FILE*
|
||||
|
||||
|
||||
const int GENERIC_READ = 1 << 0;
|
||||
const int GENERIC_WRITE = 1 << 1;
|
||||
|
||||
const int CREATE_NEW = 1;
|
||||
const int CREATE_ALWAYS = 2;
|
||||
const int OPEN_EXISTING = 3;
|
||||
const int OPEN_ALWAYS = 4;
|
||||
const int TRUNCATE_EXISTING = 5;
|
||||
|
||||
const DWORD FILE_ATTRIBUTE_NORMAL = 1;
|
||||
|
||||
const int FILE_CURRENT = SEEK_CUR;
|
||||
const int FILE_BEGIN = SEEK_SET;
|
||||
const int FILE_END = SEEK_END;
|
||||
|
||||
const int FILE_SHARE_READ = 1;
|
||||
|
||||
BOOL WriteFile(FILE* hFile, const void* lpBuffer, DWORD numBytesToWrite, DWORD* numBytesWritten, void* unsup=NULL);
|
||||
BOOL ReadFile(FILE* hFile, void* lpBuffer, DWORD numBytesToWrite, DWORD* numBytesRead, void* unsup=NULL);
|
||||
DWORD SetFilePointer(FILE* hFile, long lDistanceToMove, long* lpDistanceToMoveHigh, DWORD dwMoveMethod);
|
||||
FILE* CreateFile(const char* fileName, DWORD access, DWORD shareMode, void* unsupA, DWORD creationDisposition, DWORD flagsAndAttributes, FILE* unsup2);
|
||||
BOOL CloseHandle(FILE* hFile);
|
||||
DWORD GetFileSize(FILE* hFile, DWORD* lpHighSize);
|
||||
BOOL FileExists(const char* fileName);
|
||||
|
||||
|
||||
//Memory Support
|
||||
|
||||
const int MEM_RESERVE = 0;
|
||||
const int MEM_COMMIT = 1;
|
||||
const int PAGE_READWRITE = 0;
|
||||
const int MEM_RELEASE = 0;
|
||||
const int PAGE_NOACCESS = 0;
|
||||
|
||||
void* VirtualAlloc(void* location, DWORD size, DWORD flAllocationType, DWORD flProtect);
|
||||
BOOL VirtualFree(void* location, DWORD size, DWORD freeType);
|
||||
BOOL VirtualProtect(void* location, DWORD size, DWORD newProtect, DWORD* oldProect);
|
||||
BOOL IsBadReadPtr(const void* location, unsigned int size);
|
||||
|
||||
//Misc output stuff
|
||||
|
||||
const int MB_OK = 0;
|
||||
const int MB_ICONEXCLAMATION = 1;
|
||||
void MessageBox (void* unused, const char* message, const char* unused2, int flags);
|
||||
char *ConvertCommandLine(int argc, char ** argv);
|
||||
|
||||
//String functions
|
||||
#define _vsnprintf vsnprintf
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline int _strnicmp (const char * a, const char * b, size_t count)
|
||||
{
|
||||
return ::strncasecmp (a, b, count);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
inline int _open(const char *filename, int oflag) { return open(filename, oflag); }
|
||||
inline int _open(const char *filename, int oflag, mode_t pmode) { return open(filename, oflag, pmode); }
|
||||
inline int _creat(const char *filename, mode_t pmode) { return creat(filename, pmode); }
|
||||
inline int _close(int fd) { return close(fd); }
|
||||
inline int _write(int fd, const void *buffer, unsigned int count) { return write(fd, buffer, count); }
|
||||
inline int _dup(int fd) { return dup(fd); }
|
||||
inline int _dup2(int oldfd, int newfd) { return dup2(oldfd, newfd); }
|
||||
inline long _lseek(int fd, long offset, int origin) { return lseek(fd, offset, origin); }
|
||||
inline int _read(int fd, void *buffer, unsigned int count) { return read(fd, buffer, count); }
|
||||
inline long _tell(int fd) { return _lseek(fd,0,SEEK_CUR); }
|
||||
inline int _umask(int pmode) { return umask(pmode); }
|
||||
inline int _unlink(const char *pathname) { return unlink(pathname); }
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#endif //INCLUDED_MISC_H
|
||||
@@ -0,0 +1,185 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SetupSharedFoundation.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 - 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
|
||||
#include "sharedDebug/ConfigSharedDebugLinux.h"
|
||||
#include "sharedDebug/DebugMonitor.h"
|
||||
#include "sharedDebug/Profiler.h"
|
||||
#include "sharedFoundation/Clock.h"
|
||||
#include "sharedFoundation/CommandLine.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedFoundation/CrcLowerString.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
#include "sharedFoundation/StaticCallbackEntry.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <math.h>
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Install the engine.
|
||||
*
|
||||
* The settings in the Data structure will determine which subsystems
|
||||
* get initialized.
|
||||
*/
|
||||
|
||||
void SetupSharedFoundation::install(const Data &data)
|
||||
{
|
||||
// and get the command line stuff in quick so we can make decisions based on the command line settings
|
||||
CommandLine::install();
|
||||
ConfigFile::install();
|
||||
|
||||
if (data.lpCmdLine)
|
||||
CommandLine::absorbString(data.lpCmdLine);
|
||||
if (data.argc)
|
||||
CommandLine::absorbStrings(const_cast<const char**>(data.argv+1), data.argc-1);
|
||||
|
||||
#if 0
|
||||
//currently there's a problem that we cannot override the defaults here.
|
||||
if (data.configFile)
|
||||
IGNORE_RETURN(ConfigFile::loadFile(data.configFile));
|
||||
#endif
|
||||
|
||||
// get the post command-line text for the ConfigFile (key-value pairs)
|
||||
const char *configString = CommandLine::getPostCommandLineString();
|
||||
if (configString)
|
||||
ConfigFile::loadFromCommandLine(configString);
|
||||
|
||||
//@todo there is a lot of stuff in win32 setup not here...like exitchain
|
||||
Profiler::registerDebugFlags();
|
||||
#if _DEBUG
|
||||
MemoryManager::registerDebugFlags();
|
||||
#endif//_DEBUG
|
||||
|
||||
// Setup Linux DebugMonitor support.
|
||||
// @todo fix this dependency: DebugMonitor really should be moved into Foundation the way things currently are. TRF is following the existing win32 setup.
|
||||
#ifdef _DEBUG
|
||||
ConfigSharedDebugLinux::install();
|
||||
DebugMonitor::install();
|
||||
#endif
|
||||
|
||||
// setup the engine configuration
|
||||
ConfigSharedFoundation::Defaults defaults;
|
||||
defaults.frameRateLimit = data.frameRateLimit;
|
||||
ConfigSharedFoundation::install(defaults);
|
||||
SetWarningStrictFatal(ConfigFile::getKeyBool("SharedDebug", "strict", false));
|
||||
Report::install();
|
||||
Clock::install(data.runInBackground, false);
|
||||
|
||||
PersistentCrcString::install();
|
||||
CrcLowerString::install();
|
||||
StaticCallbackEntry::install();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Call a function with appropriate exception handling (not)
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// this is stubbed and exception handling is ignored currently
|
||||
|
||||
void SetupSharedFoundation::callbackWithExceptionHandling(
|
||||
void (*callback)(void) // Routine to call with exception handling
|
||||
)
|
||||
{
|
||||
if (ConfigSharedFoundation::getNoExceptionHandling())
|
||||
{
|
||||
callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
callback();
|
||||
}
|
||||
catch (__exception * mathException)
|
||||
{
|
||||
FATAL(true, ("Math Exception: %s\n", mathException->name));
|
||||
}
|
||||
catch (const char* message)
|
||||
{
|
||||
FATAL(true, ("Character Exception: %s\n", message));
|
||||
}
|
||||
catch(std::exception & m)
|
||||
{
|
||||
const char * c = m.what();
|
||||
FATAL(true, ("Std::exception: %s\n", c));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
FATAL(true, ("Unknown exception\n"));
|
||||
}
|
||||
#else
|
||||
callback();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Uninstall the engine.
|
||||
*
|
||||
* This routine will properly uninstall the engine componenets that were
|
||||
* installed by SetupSharedFoundation::install().
|
||||
*/
|
||||
|
||||
void SetupSharedFoundation::remove(void)
|
||||
{
|
||||
ExitChain::quit();
|
||||
|
||||
if (GetNumberOfWarnings())
|
||||
REPORT(true, Report::RF_print | Report::RF_log | Report::RF_dialog, ("%d warnings logged", GetNumberOfWarnings()));
|
||||
|
||||
// this routine can't be on the exit chain because the exit chain depends upon the PerThreadData class being around
|
||||
//PerThreadData::remove();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
SetupSharedFoundation::Data::Data(Defaults defaults)
|
||||
{
|
||||
Zero(*this);
|
||||
|
||||
switch (defaults)
|
||||
{
|
||||
case D_game:
|
||||
runInBackground = true;
|
||||
|
||||
lpCmdLine = NULL;
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
|
||||
configFile = NULL;
|
||||
|
||||
frameRateLimit = CONST_REAL(0);
|
||||
break;
|
||||
|
||||
case D_console:
|
||||
runInBackground = true;
|
||||
|
||||
lpCmdLine = NULL;
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
|
||||
configFile = NULL;
|
||||
|
||||
frameRateLimit = CONST_REAL(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_FATAL(true, ("unknown case"));
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,58 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SetupSharedFoundation.h
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_SetupSharedFoundation_H
|
||||
#define INCLUDED_SetupSharedFoundation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
struct DebugMenuEntry;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class SetupSharedFoundation
|
||||
{
|
||||
public:
|
||||
|
||||
struct Data
|
||||
{
|
||||
// allow running in background
|
||||
bool runInBackground;
|
||||
|
||||
// pointer to command line
|
||||
char* lpCmdLine;
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
const char *configFile;
|
||||
|
||||
real frameRateLimit;
|
||||
|
||||
public:
|
||||
|
||||
enum Defaults
|
||||
{
|
||||
D_game,
|
||||
D_console
|
||||
};
|
||||
|
||||
Data(Defaults defaults);
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static void install(const Data &data);
|
||||
static void remove(void);
|
||||
|
||||
static void callbackWithExceptionHandling(void (*callback)(void));
|
||||
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// vsnprintf.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/vsnprintf.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
// ======================================================================
|
||||
// Format a printf-style string into a text buffer of fixed size
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// The number of characters written into the buffer, or -1 if the buffer was too small
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// If the buffer would overflow, the null terminating character is not written and -1
|
||||
// will be returned.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
int vsnprintf(char *buffer, size_t count, const char *format, va_list va)
|
||||
{
|
||||
return _vsnprintf(buffer, count, format, va);
|
||||
}
|
||||
|
||||
#endif
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,24 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// vsnprintf.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef VSNPRINTF_H
|
||||
#define VSNPRINTF_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
int vsnprintf(char *buffer, size_t count, const char *format, va_list va);
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ApplicationVersion.cpp
|
||||
// Copyright 2002-2004, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/ApplicationVersion.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace ApplicationVersionNamespace
|
||||
{
|
||||
// WARNING do not change this string without making sure that the hardcoded offsets below are correct
|
||||
char ms_version[] = "ApplicationVersionMarker 000 123456789012345678901234567890";
|
||||
int const brandOffset = 25;
|
||||
int const bootlegOffset = 26;
|
||||
int const publishOffset = 27;
|
||||
int const versionOffset = 29;
|
||||
|
||||
bool isBranded();
|
||||
}
|
||||
using namespace ApplicationVersionNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
bool ApplicationVersionNamespace::isBranded()
|
||||
{
|
||||
return ms_version[brandOffset] == '1';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ApplicationVersion::isBootlegBuild()
|
||||
{
|
||||
return ms_version[bootlegOffset] == '1';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool ApplicationVersion::isPublishBuild()
|
||||
{
|
||||
return ms_version[publishOffset] == '1';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const char * ApplicationVersion::getPublicVersion()
|
||||
{
|
||||
if (!isBranded())
|
||||
return "0";
|
||||
|
||||
char const * internal = ms_version + versionOffset;
|
||||
while (*internal != '\0' && *internal != '.')
|
||||
++internal;
|
||||
|
||||
if (*internal == '\0' || internal[1] == '\0')
|
||||
return "0";
|
||||
|
||||
return internal + 1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
char const * ApplicationVersion::getInternalVersion()
|
||||
{
|
||||
if (!isBranded())
|
||||
return "unknown.0";
|
||||
|
||||
return ms_version + versionOffset;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,25 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ApplicationVersion.h
|
||||
// Copyright 2002-2004, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ApplicationVersion_H
|
||||
#define INCLUDED_ApplicationVersion_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ApplicationVersion
|
||||
{
|
||||
public:
|
||||
static bool isBootlegBuild();
|
||||
static bool isPublishBuild();
|
||||
static char const * getPublicVersion();
|
||||
static char const * getInternalVersion();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,552 @@
|
||||
//===================================================================
|
||||
//
|
||||
// ArrayList.h
|
||||
// asommers 10-2-98
|
||||
//
|
||||
// copyright 1998, bootprint entertainment
|
||||
// copyright 2001, sony online entertainment
|
||||
//
|
||||
// generic list template
|
||||
//
|
||||
// @todo replace instances of ArrayList with std::vector
|
||||
//
|
||||
//===================================================================
|
||||
|
||||
#ifndef INCLUDED_ArrayList_H
|
||||
#define INCLUDED_ArrayList_H
|
||||
|
||||
//===================================================================
|
||||
|
||||
template <class T>
|
||||
class ArrayList
|
||||
{
|
||||
public:
|
||||
|
||||
// construction/destruction
|
||||
explicit ArrayList (int newSize=0);
|
||||
ArrayList (const ArrayList<T>& rhs);
|
||||
~ArrayList (void);
|
||||
|
||||
// allow preallocation of list
|
||||
void preallocate (int newSize, bool numberOfElementsToo=false);
|
||||
void preallocateAndSet (int newSize, const T& newValue);
|
||||
|
||||
// destroy the list if it was created statically
|
||||
void destroy (void);
|
||||
|
||||
// clear out the list
|
||||
void clear (void);
|
||||
|
||||
// add a new item to the list
|
||||
void add (const T& newElement);
|
||||
void addIfNotExist (const T& newElement);
|
||||
void allocateNext (void);
|
||||
int findOrAdd (const T& newElement);
|
||||
|
||||
void insert (int index, const T& newElement);
|
||||
|
||||
// remove an item from the list
|
||||
void remove (const T& element, bool mustExist=false);
|
||||
void removeIndexAndCompactList (int index);
|
||||
|
||||
// delete the last item from the list
|
||||
// NOTE: caller should know how to delete the element if necessary
|
||||
void deleteLast (void);
|
||||
|
||||
// returns true if element is already in the list
|
||||
bool existsInList (const T& element) const;
|
||||
bool existsInList (const T& element, int& index) const;
|
||||
|
||||
// returns the number of elements in the list
|
||||
int getNumberOfElements (void) const;
|
||||
|
||||
// returns the index'th item in the list (DOES NOT check for out of bounds)
|
||||
T& getElement (int index);
|
||||
const T& getElement (int index) const;
|
||||
T& getLastElement (void);
|
||||
const T& getLastElement (void) const;
|
||||
|
||||
// returns the index'th item in the list (DOES NOT check for out of bounds)
|
||||
T& operator[] (int index);
|
||||
const T& operator[] (int index) const;
|
||||
|
||||
//
|
||||
ArrayList<T>& operator= (const ArrayList<T>& rhs);
|
||||
|
||||
// swapping
|
||||
void swap (int index1, int index2);
|
||||
|
||||
// stl interface to make transition easier
|
||||
const T& back () const;
|
||||
T& back ();
|
||||
int size () const;
|
||||
bool empty () const;
|
||||
void push_back (const T& element);
|
||||
void pop_back ();
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
DEFAULT_SIZE = 16 // initial list m_size
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// resizes the list
|
||||
void resizeUp (void);
|
||||
|
||||
void copy (const ArrayList<T>& rhs);
|
||||
|
||||
private:
|
||||
|
||||
int m_size; // list m_size
|
||||
T* m_data; // list m_data
|
||||
int m_numberOfElements; // number of items in the list
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
|
||||
template <class T>
|
||||
inline ArrayList<T>::ArrayList (int newSize) :
|
||||
m_size (newSize),
|
||||
m_data (0),
|
||||
m_numberOfElements (0)
|
||||
{
|
||||
if (newSize)
|
||||
m_data = new T [m_size];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline ArrayList<T>::ArrayList (const ArrayList<T>& rhs) :
|
||||
m_size (0),
|
||||
m_data (0),
|
||||
m_numberOfElements (0)
|
||||
{
|
||||
copy (rhs);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline ArrayList<T>& ArrayList<T>::operator= (const ArrayList<T>& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
copy (rhs);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::copy (const ArrayList<T>& rhs)
|
||||
{
|
||||
// only delete and re-new the list if we don't have enough elements to hold the contents of rhs
|
||||
if (m_numberOfElements < rhs.m_numberOfElements)
|
||||
{
|
||||
if (m_data)
|
||||
delete [] m_data;
|
||||
|
||||
m_size = rhs.m_size;
|
||||
m_data = new T [m_size];
|
||||
}
|
||||
|
||||
// only copy the vital elements
|
||||
memcpy (m_data, rhs.m_data, sizeof (T) * rhs.m_numberOfElements);
|
||||
|
||||
m_numberOfElements = rhs.m_numberOfElements;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::destroy (void)
|
||||
{
|
||||
delete [] m_data;
|
||||
m_data = 0;
|
||||
|
||||
m_size = 0;
|
||||
m_numberOfElements = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline ArrayList<T>::~ArrayList (void)
|
||||
{
|
||||
destroy ();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::preallocate (int newSize, bool numberOfElementsToo)
|
||||
{
|
||||
// if the m_size we want to preallocate is greater than our current m_size, grow to fit
|
||||
if (newSize > m_size)
|
||||
{
|
||||
delete [] m_data;
|
||||
m_data = new T [newSize];
|
||||
m_size = newSize;
|
||||
}
|
||||
|
||||
if (numberOfElementsToo)
|
||||
m_numberOfElements = newSize;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::preallocateAndSet (int newSize, const T& newValue)
|
||||
{
|
||||
preallocate (newSize, true);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < newSize; i++)
|
||||
m_data [i] = newValue;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::clear (void)
|
||||
{
|
||||
m_numberOfElements = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::add (const T& newElement)
|
||||
{
|
||||
// is the list full? if so, resize it
|
||||
if (m_numberOfElements == m_size)
|
||||
resizeUp ();
|
||||
|
||||
// add the m_data to the list
|
||||
NOT_NULL (m_data);
|
||||
m_data [m_numberOfElements++] = newElement;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::addIfNotExist (const T& newElement)
|
||||
{
|
||||
if (existsInList (newElement))
|
||||
return;
|
||||
|
||||
add (newElement);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline int ArrayList<T>::findOrAdd (const T& newElement)
|
||||
{
|
||||
if (existsInList (newElement, index))
|
||||
return index;
|
||||
|
||||
add (newElement);
|
||||
|
||||
return getNumberOfElements () - 1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::insert (int index, const T& newElement)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
|
||||
//-- if inserting at end, just add it
|
||||
if (index == m_numberOfElements)
|
||||
add (newElement);
|
||||
else
|
||||
{
|
||||
//-- is the list full? if so, resize it
|
||||
if (m_numberOfElements == m_size)
|
||||
resizeUp ();
|
||||
|
||||
//-- move everything from index to end of list down
|
||||
int i;
|
||||
for (i = m_numberOfElements - 1; i >= index; --i)
|
||||
m_data [i + 1] = m_data [i];
|
||||
|
||||
//-- insert item into list
|
||||
m_data [index] = newElement;
|
||||
m_numberOfElements++;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::allocateNext (void)
|
||||
{
|
||||
// is the list full? if so, resize it
|
||||
if (m_numberOfElements == m_size)
|
||||
resizeUp ();
|
||||
|
||||
m_numberOfElements++;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::remove (const T& element, bool mustExist)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
|
||||
// search the list for the element
|
||||
int i;
|
||||
for (i = 0; i < m_numberOfElements; i++)
|
||||
{
|
||||
// if we found it
|
||||
if (m_data [i] == element)
|
||||
{
|
||||
// squish list
|
||||
int j;
|
||||
for (j = i; j < m_numberOfElements-1; j++)
|
||||
m_data [j] = m_data [j+1];
|
||||
|
||||
m_numberOfElements--;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UNREF (mustExist);
|
||||
DEBUG_FATAL (mustExist, ("ArrayList<T>::remove - not found in list"));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::removeIndexAndCompactList (int index)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (index < 0 || index >= m_numberOfElements, ("index %d out of range", index));
|
||||
|
||||
// squish list
|
||||
int j;
|
||||
for (j = index; j < m_numberOfElements-1; j++)
|
||||
m_data [j] = m_data [j+1];
|
||||
|
||||
m_numberOfElements--;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::deleteLast (void)
|
||||
{
|
||||
if (m_numberOfElements > 0)
|
||||
m_numberOfElements--;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline bool ArrayList<T>::existsInList (const T& element) const
|
||||
{
|
||||
if (m_numberOfElements > 0)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < m_numberOfElements; i++)
|
||||
if (m_data [i] == element)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline bool ArrayList<T>::existsInList (const T& element, int& index) const
|
||||
{
|
||||
if (m_numberOfElements > 0)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < m_numberOfElements; i++)
|
||||
if (m_data [i] == element)
|
||||
{
|
||||
index = i;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::resizeUp (void)
|
||||
{
|
||||
// allocate new memory for the list (just double it)
|
||||
int newSize = m_size ? m_size * 2 : DEFAULT_SIZE;
|
||||
|
||||
T* newData = new T [newSize];
|
||||
|
||||
// copy the contents of the old list into the new list
|
||||
if (m_data)
|
||||
memcpy (newData, m_data, sizeof (T) * m_size);
|
||||
|
||||
// increase the m_size
|
||||
m_size = newSize;
|
||||
|
||||
// zap the old list
|
||||
delete [] m_data;
|
||||
|
||||
// point to the new list
|
||||
m_data = newData;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline int ArrayList<T>::getNumberOfElements (void) const
|
||||
{
|
||||
return m_numberOfElements;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline const T& ArrayList<T>::getElement (int index) const
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (index < 0 || index >= m_numberOfElements, ("index %d out of range", index));
|
||||
|
||||
return m_data [index];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline const T& ArrayList<T>::getLastElement (void) const
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (m_numberOfElements == 0, ("ArrayList<T>::getLastElement - list has no elements"));
|
||||
|
||||
return m_data [m_numberOfElements - 1];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline const T& ArrayList<T>::operator[] (int index) const
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (index < 0 || index >= m_numberOfElements, ("index %d out of range", index));
|
||||
|
||||
return m_data [index];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline T& ArrayList<T>::getElement (int index)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (index < 0 || index >= m_numberOfElements, ("index %d out of range", index));
|
||||
|
||||
return m_data [index];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline T& ArrayList<T>::getLastElement (void)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (m_numberOfElements == 0, ("ArrayList<T>::getLastElement - list has no elements"));
|
||||
|
||||
return m_data [m_numberOfElements - 1];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline T& ArrayList<T>::operator[] (int index)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (index < 0 || index >= m_numberOfElements, ("index %d out of range", index));
|
||||
|
||||
return m_data [index];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::swap (int index1, int index2)
|
||||
{
|
||||
NOT_NULL (m_data);
|
||||
DEBUG_FATAL (index1 < 0 || index1 >= m_numberOfElements || index2 < 0 || index2 >= m_numberOfElements, ("ArrayList<T>::swap - index1 %d or index2 %d out of range", index1, index2));
|
||||
|
||||
T tmp = m_data [index1];
|
||||
m_data [index1] = m_data [index2];
|
||||
m_data [index2] = tmp;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline const T& ArrayList<T>::back () const
|
||||
{
|
||||
return getLastElement ();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline T& ArrayList<T>::back ()
|
||||
{
|
||||
return getLastElement ();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline int ArrayList<T>::size () const
|
||||
{
|
||||
return getNumberOfElements ();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline bool ArrayList<T>::empty () const
|
||||
{
|
||||
return getNumberOfElements () == 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::push_back (const T& element)
|
||||
{
|
||||
add (element);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
inline void ArrayList<T>::pop_back ()
|
||||
{
|
||||
deleteLast ();
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// AutoDeltaNetworkIdPackedMap.cpp
|
||||
// copyright (c) 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/AutoDeltaNetworkIdPackedMap.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
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
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,100 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// AutoDeltaNetworkIdPackedMap.h
|
||||
// copyright (c) 2004 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_AutoDeltaNetworkIdPackedMap_H
|
||||
#define INCLUDED_AutoDeltaNetworkIdPackedMap_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "Archive/AutoDeltaMap.h"
|
||||
#include <stdio.h>
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
#include "sharedFoundation/NetworkIdArchive.h"
|
||||
#include "Archive/AutoDeltaPackedMap.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
/**
|
||||
* An AutoDeltaNetworkIdPackedMap 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.
|
||||
*/
|
||||
|
||||
void AutoDeltaPackedMap<NetworkId, int>::pack(ByteStream & target, const std::string & buffer)
|
||||
{
|
||||
char temp[200];
|
||||
AutoDeltaMap<NetworkId, int>::Command c;
|
||||
|
||||
Archive::put(target, countCharacter(buffer,':'));
|
||||
Archive::put(target, static_cast<size_t>(0)); // baselineCommandCount
|
||||
|
||||
int tempPos = 0;
|
||||
for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i)
|
||||
{
|
||||
if (*i==':')
|
||||
{
|
||||
temp[tempPos]='\0';
|
||||
sscanf(temp, "%d", &c.value);
|
||||
Archive::put(target, static_cast<unsigned char>(AutoDeltaMap<NetworkId, int>::Command::ADD));
|
||||
Archive::put(target, c.key);
|
||||
Archive::put(target, c.value);
|
||||
tempPos=0;
|
||||
}
|
||||
else if (*i == ' ')
|
||||
{
|
||||
temp[tempPos] = '\0';
|
||||
c.key = NetworkId(temp);
|
||||
tempPos = 0;
|
||||
}
|
||||
else
|
||||
temp[tempPos++]=*i;
|
||||
}
|
||||
}
|
||||
|
||||
void AutoDeltaPackedMap<NetworkId, int>::unpack(ReadIterator & source, std::string & buffer)
|
||||
{
|
||||
char temp[200];
|
||||
|
||||
AutoDeltaMap<NetworkId, int>::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, "%s %d:", c.key.getValueString().c_str(), c.value);
|
||||
#else
|
||||
snprintf(temp, sizeof(temp)-1, "%s %d:", c.key.getValueString().c_str(), c.value);
|
||||
#endif
|
||||
|
||||
temp[sizeof(temp)-1]='\0';
|
||||
buffer+=temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Binary.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef BINARY_H
|
||||
#define BINARY_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
//lint -save -e1923 // could become const variable
|
||||
|
||||
#define HEX_DIGIT_0000 0
|
||||
#define HEX_DIGIT_0001 1
|
||||
#define HEX_DIGIT_0010 2
|
||||
#define HEX_DIGIT_0011 3
|
||||
#define HEX_DIGIT_0100 4
|
||||
#define HEX_DIGIT_0101 5
|
||||
#define HEX_DIGIT_0110 6
|
||||
#define HEX_DIGIT_0111 7
|
||||
#define HEX_DIGIT_1000 8
|
||||
#define HEX_DIGIT_1001 9
|
||||
#define HEX_DIGIT_1010 a
|
||||
#define HEX_DIGIT_1011 b
|
||||
#define HEX_DIGIT_1100 c
|
||||
#define HEX_DIGIT_1101 d
|
||||
#define HEX_DIGIT_1110 e
|
||||
#define HEX_DIGIT_1111 f
|
||||
|
||||
//line -restore
|
||||
|
||||
#define HEX_DIGIT(a) HEX_DIGIT_ ## a
|
||||
|
||||
#define BINARY1H(a) (0x ## a)
|
||||
#define BINARY1I(a) BINARY1H(a)
|
||||
#define BINARY1(a) BINARY1I(HEX_DIGIT(a))
|
||||
|
||||
#define BINARY2H(a,b) (0x ## a ## b)
|
||||
#define BINARY2I(a,b) BINARY2H(a,b)
|
||||
#define BINARY2(a,b) BINARY2I(HEX_DIGIT(a), HEX_DIGIT(b))
|
||||
|
||||
#define BINARY3H(a,b,c) (0x ## a ## b ## c)
|
||||
#define BINARY3I(a,b,c) BINARY3H(a,b,c)
|
||||
#define BINARY3(a,b,c) BINARY3I(HEX_DIGIT(a), HEX_DIGIT(b), HEX_DIGIT(c))
|
||||
|
||||
#define BINARY4H(a,b,c,d) (0x ## a ## b ## c ## d)
|
||||
#define BINARY4I(a,b,c,d) BINARY4H(a,b,c,d)
|
||||
#define BINARY4(a,b,c,d) BINARY4I(HEX_DIGIT(a), HEX_DIGIT(b), HEX_DIGIT(c), HEX_DIGIT(d))
|
||||
|
||||
#define BINARY5H(a,b,c,d,e) (0x ## a ## b ## c ## d ## e)
|
||||
#define BINARY5I(a,b,c,d,e) BINARY5H(a,b,c,d,e)
|
||||
#define BINARY5(a,b,c,d,e) BINARY5I(HEX_DIGIT(a), HEX_DIGIT(b), HEX_DIGIT(c), HEX_DIGIT(d), HEX_DIGIT(e))
|
||||
|
||||
#define BINARY6H(a,b,c,d,e,f) (0x ## a ## b ## c ## d ## e ## f)
|
||||
#define BINARY6I(a,b,c,d,e,f) BINARY6H(a,b,c,d,e,f)
|
||||
#define BINARY6(a,b,c,d,e,f) BINARY6I(HEX_DIGIT(a), HEX_DIGIT(b), HEX_DIGIT(c), HEX_DIGIT(d), HEX_DIGIT(e), HEX_DIGIT(f))
|
||||
|
||||
#define BINARY7H(a,b,c,d,e,f,g) (0x ## a ## b ## c ## d ## e ## f ## g)
|
||||
#define BINARY7I(a,b,c,d,e,f,g) BINARY7H(a,b,c,d,e,f,g)
|
||||
#define BINARY7(a,b,c,d,e,f,g) BINARY7I(HEX_DIGIT(a), HEX_DIGIT(b), HEX_DIGIT(c), HEX_DIGIT(d), HEX_DIGIT(e), HEX_DIGIT(f), HEX_DIGIT(g))
|
||||
|
||||
#define BINARY8H(a,b,c,d,e,f,g,h) (0x ## a ## b ## c ## d ## e ## f ## g ## h)
|
||||
#define BINARY8I(a,b,c,d,e,f,g,h) BINARY8H(a,b,c,d,e,f,g,h)
|
||||
#define BINARY8(a,b,c,d,e,f,g,h) BINARY8I(HEX_DIGIT(a), HEX_DIGIT(b), HEX_DIGIT(c), HEX_DIGIT(d), HEX_DIGIT(e), HEX_DIGIT(f), HEX_DIGIT(g), HEX_DIGIT(h))
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,621 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// BitArray.cpp
|
||||
// Copyright 2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/BitArray.h"
|
||||
|
||||
#include "Archive/Archive.h"
|
||||
#include "sharedFoundation/FormattedString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
BitArray::BitArray() :
|
||||
m_arrayData(m_defaultData),
|
||||
m_numAllocatedBytes(sizeof(m_defaultData)),
|
||||
m_numInUseBytes(0),
|
||||
m_numInUseBits(0)
|
||||
{
|
||||
memset(m_arrayData, 0, m_numAllocatedBytes);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
BitArray::BitArray(int numBits) :
|
||||
m_arrayData(m_defaultData),
|
||||
m_numAllocatedBytes(sizeof(m_defaultData)),
|
||||
m_numInUseBytes(0),
|
||||
m_numInUseBits(0)
|
||||
{
|
||||
if (numBits > (m_numAllocatedBytes << 3))
|
||||
{
|
||||
m_arrayData = NULL;
|
||||
m_numAllocatedBytes = 0;
|
||||
reserve(numBits);
|
||||
m_numInUseBytes = 0;
|
||||
m_numInUseBits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(m_arrayData, 0, m_numAllocatedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
BitArray::BitArray(const BitArray &orig) :
|
||||
m_arrayData(m_defaultData),
|
||||
m_numAllocatedBytes(sizeof(m_defaultData)),
|
||||
m_numInUseBytes(0),
|
||||
m_numInUseBits(0)
|
||||
{
|
||||
if (orig.m_numInUseBytes > m_numAllocatedBytes)
|
||||
{
|
||||
m_arrayData = new signed char[static_cast<size_t>(orig.m_numInUseBytes)];
|
||||
m_numAllocatedBytes = orig.m_numInUseBytes;
|
||||
}
|
||||
|
||||
m_numInUseBytes = orig.m_numInUseBytes;
|
||||
m_numInUseBits = orig.m_numInUseBits;
|
||||
|
||||
if (m_numInUseBytes > 0)
|
||||
{
|
||||
memcpy(m_arrayData, orig.m_arrayData, m_numInUseBytes);
|
||||
|
||||
if (m_numAllocatedBytes > m_numInUseBytes)
|
||||
memset(&(m_arrayData[m_numInUseBytes]), 0, static_cast<size_t>(m_numAllocatedBytes - m_numInUseBytes));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(m_arrayData, 0, m_numAllocatedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
BitArray::~BitArray()
|
||||
{
|
||||
if (m_arrayData != m_defaultData)
|
||||
delete []m_arrayData;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
BitArray & BitArray::operator= (const BitArray &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
// trivial case, rhs is empty
|
||||
if ((rhs.m_numInUseBits <= 0) || (rhs.m_numInUseBytes <= 0))
|
||||
{
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// char array is too small, reallocate new char array
|
||||
if (m_numAllocatedBytes < rhs.m_numInUseBytes)
|
||||
{
|
||||
if (m_arrayData != m_defaultData)
|
||||
delete []m_arrayData;
|
||||
|
||||
m_arrayData = new signed char[static_cast<size_t>(rhs.m_numInUseBytes)];
|
||||
m_numAllocatedBytes = rhs.m_numInUseBytes;
|
||||
}
|
||||
// char array is large enough, no reallocation required,
|
||||
// but clear out char array, if necessary
|
||||
else if (m_numInUseBytes > rhs.m_numInUseBytes)
|
||||
{
|
||||
memset(&(m_arrayData[rhs.m_numInUseBytes]), 0, static_cast<size_t>(m_numInUseBytes - rhs.m_numInUseBytes));
|
||||
}
|
||||
|
||||
m_numInUseBytes = rhs.m_numInUseBytes;
|
||||
m_numInUseBits = rhs.m_numInUseBits;
|
||||
memcpy(m_arrayData, rhs.m_arrayData, static_cast<size_t>(m_numInUseBytes));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
bool BitArray::operator== (const BitArray &rhs) const
|
||||
{
|
||||
//-- Check for self equality
|
||||
if (this == &rhs)
|
||||
return true;
|
||||
|
||||
// compare the individual chars in the 2 array up to the number
|
||||
// of chars needed to hold the smaller of the 2 m_numInUseBits
|
||||
int const smallerArraySize = std::min(m_numInUseBytes, rhs.m_numInUseBytes);
|
||||
for (int i = 0; i < smallerArraySize; ++i)
|
||||
if (m_arrayData[i] != rhs.m_arrayData[i])
|
||||
return false;
|
||||
|
||||
// if there are any additional set bits (i.e. non-zero char)
|
||||
// in the larger of the 2 arrays, then equality is false
|
||||
if (m_numInUseBytes != rhs.m_numInUseBytes)
|
||||
{
|
||||
signed char const * largerArrayData;
|
||||
int largerArraySize;
|
||||
|
||||
if (m_numInUseBytes > rhs.m_numInUseBytes)
|
||||
{
|
||||
largerArraySize = m_numInUseBytes;
|
||||
largerArrayData = m_arrayData;
|
||||
}
|
||||
else
|
||||
{
|
||||
largerArraySize = rhs.m_numInUseBytes;
|
||||
largerArrayData = rhs.m_arrayData;
|
||||
}
|
||||
|
||||
for (int j = smallerArraySize; j < largerArraySize; ++j)
|
||||
if (largerArrayData[j])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool BitArray::operator!=(const BitArray &rhs) const
|
||||
{
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::setBit(int const index)
|
||||
{
|
||||
DEBUG_FATAL(index < 0, ("BitArray::setBit index [%d] out of range", index));
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
if (index >= m_numInUseBits)
|
||||
reserve(index+1);
|
||||
|
||||
int const arrayPos = index >> 3; //lint !e702 shift right of signed quantity (DEBUG_FATALs if index < 0)
|
||||
int const bitPos = index & 7;
|
||||
m_arrayData[arrayPos] |= (1 << bitPos);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::setValue(int const beginIndex, int const endIndex, unsigned long value)
|
||||
{
|
||||
DEBUG_FATAL(beginIndex < 0, ("BitArray::setValue beginIndex [%d] out of range", beginIndex));
|
||||
DEBUG_FATAL(endIndex < 0, ("BitArray::setValue endIndex [%d] out of range", endIndex));
|
||||
DEBUG_FATAL(beginIndex > endIndex, ("BitArray::setValue beginIndex [%d] > endIndex [%d]", beginIndex, endIndex));
|
||||
|
||||
if ((beginIndex >= 0) && (endIndex >= 0) && (beginIndex <= endIndex))
|
||||
{
|
||||
int currentIndex = beginIndex;
|
||||
while (currentIndex <= endIndex)
|
||||
{
|
||||
if (value == 0)
|
||||
break;
|
||||
|
||||
if (value & 0x1)
|
||||
setBit(currentIndex++);
|
||||
else
|
||||
clearBit(currentIndex++);
|
||||
|
||||
value >>= 1;
|
||||
}
|
||||
|
||||
for (int i = currentIndex; i <= endIndex; ++i)
|
||||
clearBit(i);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::clearBit(int const index)
|
||||
{
|
||||
DEBUG_FATAL(index < 0, ("BitArray::clearBit index [%d] out of range", index));
|
||||
|
||||
if ((index >= 0) && (index < m_numInUseBits))
|
||||
{
|
||||
int const arrayPos = index >> 3; //lint !e702 shift right of signed quantity (DEBUG_FATALs if index < 0)
|
||||
int const bitPos = index & 7;
|
||||
m_arrayData[static_cast<size_t>(arrayPos)] &= ~(1 << bitPos);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool BitArray::testBit(int const index) const
|
||||
{
|
||||
DEBUG_FATAL(index < 0, ("BitArray::testBit index [%d] out of range", index));
|
||||
|
||||
if ((index < 0) || (index >= m_numInUseBits))
|
||||
return false;
|
||||
|
||||
int const arrayPos = index >> 3; //lint !e702 shift right of signed quantity (DEBUG_FATALs if index < 0)
|
||||
int const bitPos = index & 7;
|
||||
return ((m_arrayData[arrayPos] & (1 << bitPos)) != 0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
unsigned long BitArray::getValue(int const beginIndex, int const endIndex) const
|
||||
{
|
||||
DEBUG_FATAL(beginIndex < 0, ("BitArray::setValue beginIndex [%d] out of range", beginIndex));
|
||||
DEBUG_FATAL(endIndex < 0, ("BitArray::setValue endIndex [%d] out of range", endIndex));
|
||||
DEBUG_FATAL(beginIndex > endIndex, ("BitArray::setValue beginIndex [%d] > endIndex [%d]", beginIndex, endIndex));
|
||||
|
||||
unsigned long value = 0;
|
||||
if ((beginIndex >= 0) && (endIndex >= 0) && (beginIndex <= endIndex))
|
||||
{
|
||||
for (int i = endIndex; i >= beginIndex; --i)
|
||||
{
|
||||
if (value)
|
||||
value <<= 1;
|
||||
|
||||
if (testBit(i))
|
||||
++value;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::reserve(int const numBits)
|
||||
{
|
||||
DEBUG_FATAL(numBits < 0, ("BitArray::reserve number of bits [%d] out of range", numBits));
|
||||
|
||||
if (numBits > 0)
|
||||
{
|
||||
// if shrinking, make sure to clear all the bits between
|
||||
// the new size and the old size to to maintain requirement
|
||||
// that every bit past 0-based index (m_numInUseBits - 1) is
|
||||
// guaranteed to be unset
|
||||
if (numBits < m_numInUseBits)
|
||||
{
|
||||
for (int i = numBits; i < m_numInUseBits; ++i)
|
||||
clearBit(i);
|
||||
}
|
||||
|
||||
m_numInUseBits = numBits;
|
||||
|
||||
int const oldNumInUseBytes = m_numInUseBytes;
|
||||
m_numInUseBytes = (m_numInUseBits + 7) >> 3;
|
||||
|
||||
if (m_numInUseBytes > m_numAllocatedBytes)
|
||||
{
|
||||
signed char * tmp = new signed char[static_cast<size_t>(m_numInUseBytes)];
|
||||
memset(&(tmp[oldNumInUseBytes]), 0, static_cast<size_t>(m_numInUseBytes - oldNumInUseBytes));
|
||||
if ((oldNumInUseBytes > 0) && (m_arrayData != NULL))
|
||||
memcpy(tmp, m_arrayData, static_cast<size_t>(oldNumInUseBytes)); //lint !e671 !e670 logically, you can't enter this code block unless oldNumInUseBytes is smaller.
|
||||
|
||||
m_numAllocatedBytes = m_numInUseBytes;
|
||||
|
||||
if (m_arrayData != m_defaultData)
|
||||
delete []m_arrayData;
|
||||
|
||||
m_arrayData = tmp;
|
||||
}
|
||||
}
|
||||
else if (numBits == 0)
|
||||
{
|
||||
if (m_arrayData != m_defaultData)
|
||||
delete []m_arrayData;
|
||||
|
||||
m_arrayData = m_defaultData;
|
||||
m_numAllocatedBytes = sizeof(m_defaultData);
|
||||
m_numInUseBytes = 0;
|
||||
m_numInUseBits = 0;
|
||||
|
||||
memset(m_arrayData, 0, m_numAllocatedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
bool BitArray::match(BitArray const & rhs) const
|
||||
{
|
||||
return operator==(rhs);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool BitArray::matchAnyBit(BitArray const & rhs) const
|
||||
{
|
||||
// compare the individual chars in the 2 array up to the number
|
||||
// of chars needed to hold the smaller of the 2 m_numInUseBits
|
||||
int const smallerArraySize = std::min(m_numInUseBytes, rhs.m_numInUseBytes);
|
||||
for (int i = 0; i < smallerArraySize; ++i)
|
||||
if (m_arrayData[i] & rhs.m_arrayData[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
void get(ReadIterator &source, BitArray &target)
|
||||
{
|
||||
int numInUseBytes;
|
||||
int numInUseBits;
|
||||
|
||||
get(source, numInUseBytes);
|
||||
get(source, numInUseBits);
|
||||
|
||||
// trivial case, rhs is empty
|
||||
if ((numInUseBits <= 0) || (numInUseBytes <= 0))
|
||||
{
|
||||
target.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// char array is too small, reallocate new char array
|
||||
if (target.m_numAllocatedBytes < numInUseBytes)
|
||||
{
|
||||
if (target.m_arrayData != target.m_defaultData)
|
||||
delete []target.m_arrayData;
|
||||
|
||||
target.m_arrayData = new signed char[static_cast<size_t>(numInUseBytes)];
|
||||
target.m_numAllocatedBytes = numInUseBytes;
|
||||
}
|
||||
// char array is large enough, no reallocation required,
|
||||
// but clear out char array, if necessary
|
||||
else if (target.m_numInUseBytes > numInUseBytes)
|
||||
{
|
||||
memset(&(target.m_arrayData[numInUseBytes]), 0, static_cast<size_t>(target.m_numInUseBytes - numInUseBytes));
|
||||
}
|
||||
|
||||
target.m_numInUseBytes = numInUseBytes;
|
||||
target.m_numInUseBits = numInUseBits;
|
||||
|
||||
for (int i = 0; i < target.m_numInUseBytes; ++i)
|
||||
{
|
||||
get(source, target.m_arrayData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void put(ByteStream &target, const BitArray &source)
|
||||
{
|
||||
put(target, source.m_numInUseBytes);
|
||||
put(target, source.m_numInUseBits);
|
||||
if ((source.m_numInUseBits > 0) && (source.m_numInUseBytes > 0))
|
||||
{
|
||||
put(target, source.m_arrayData, source.m_numInUseBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::clear()
|
||||
{
|
||||
if (m_numInUseBytes > 0)
|
||||
{
|
||||
memset(m_arrayData, 0, static_cast<size_t>(m_numInUseBytes));
|
||||
m_numInUseBytes = 0;
|
||||
m_numInUseBits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::setMultipleBits(int const count)
|
||||
{
|
||||
if (count <= 0)
|
||||
return;
|
||||
|
||||
if (count > m_numInUseBits)
|
||||
reserve(count);
|
||||
|
||||
int const charCount = (count >> 3);
|
||||
if (charCount)
|
||||
memset(m_arrayData, static_cast<unsigned>(0xFFFFFFFF), static_cast<size_t>(charCount));
|
||||
|
||||
for (int i = (charCount << 3); i < count; ++i)
|
||||
setBit(i);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::insertBit(int const index, bool const value)
|
||||
{
|
||||
DEBUG_FATAL(index < 0, ("BitArray::insertBit index [%d] out of range", index));
|
||||
|
||||
// nothing to do if inserting a new bit past
|
||||
// the end and the new bit will not be set
|
||||
if (!value && (index >= m_numInUseBits))
|
||||
return;
|
||||
|
||||
// if inserting a new bit in the middle, then shift all
|
||||
// bits at and after the insertion point "backward"
|
||||
if (index >= 0 && index < m_numInUseBits)
|
||||
{
|
||||
for(int i = (m_numInUseBits - 1); i >= index; --i)
|
||||
{
|
||||
if (testBit(i))
|
||||
setBit(i + 1);
|
||||
else
|
||||
clearBit(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// set/clear the inserted bit
|
||||
if (value)
|
||||
setBit(index);
|
||||
else
|
||||
clearBit(index);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::removeBit(int const index)
|
||||
{
|
||||
DEBUG_FATAL(index < 0, ("BitArray::removeBit index [%d] out of range", index));
|
||||
|
||||
// shift all bits after the removal point "forward"
|
||||
if (index >= 0 && index < m_numInUseBits)
|
||||
{
|
||||
int const lastBitIndexToShift = m_numInUseBits - 1;
|
||||
for(int i = index; i < lastBitIndexToShift; ++i)
|
||||
{
|
||||
if (testBit(i + 1))
|
||||
setBit(i);
|
||||
else
|
||||
clearBit(i);
|
||||
}
|
||||
|
||||
// shrink the array by 1
|
||||
reserve(m_numInUseBits - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
int BitArray::getNumberOfSetBits() const
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < m_numInUseBits; ++i)
|
||||
if (testBit(i))
|
||||
++count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
bool BitArray::empty() const
|
||||
{
|
||||
for (size_t i = 0; i < static_cast<size_t>(m_numInUseBytes); ++i)
|
||||
{
|
||||
if (m_arrayData[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::getAsDbTextString(std::string &result, int const maxNibbleCount /*= 32767*/) const
|
||||
{
|
||||
result.clear();
|
||||
|
||||
static const char hexDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
bool anyBitSet = false;
|
||||
unsigned char nibbleIntValue;
|
||||
int const nibbleCount = std::min(maxNibbleCount, (m_numInUseBytes << 1));
|
||||
for (int i = (nibbleCount - 1); i >= 0; --i)
|
||||
{
|
||||
nibbleIntValue = static_cast<unsigned char>(m_arrayData[i >> 1]);
|
||||
if (i % 2)
|
||||
nibbleIntValue >>= 4;
|
||||
else
|
||||
nibbleIntValue &= static_cast<unsigned char>(0xF);
|
||||
|
||||
if (nibbleIntValue && !anyBitSet)
|
||||
{
|
||||
anyBitSet = true;
|
||||
result.resize(i + 1);
|
||||
}
|
||||
|
||||
if (anyBitSet)
|
||||
result[i] = hexDigits[nibbleIntValue];
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void BitArray::setFromDbTextString(const char * text)
|
||||
{
|
||||
clear();
|
||||
|
||||
int const nibbleCount = (text ? strlen(text) : 0);
|
||||
if (nibbleCount > 0)
|
||||
{
|
||||
bool anyBitSet = false;
|
||||
unsigned char nibbleIntValue;
|
||||
|
||||
// set the highest index bit first to avoid constant reallocation
|
||||
for (int i = (nibbleCount - 1); i >= 0; --i)
|
||||
{
|
||||
if ((text[i] >= '0') && (text[i] <= '9'))
|
||||
nibbleIntValue = static_cast<unsigned char>(text[i] - '0');
|
||||
else if ((text[i] >= 'A') && (text[i] <= 'F'))
|
||||
nibbleIntValue = static_cast<unsigned char>(text[i] - 'A' + 10);
|
||||
else if ((text[i] >= 'a') && (text[i] <= 'f'))
|
||||
nibbleIntValue = static_cast<unsigned char>(text[i] - 'a' + 10);
|
||||
else
|
||||
nibbleIntValue = static_cast<unsigned char>(0);
|
||||
|
||||
if (nibbleIntValue)
|
||||
{
|
||||
if (!anyBitSet)
|
||||
{
|
||||
anyBitSet = true;
|
||||
reserve(((i >> 1) + 1) << 3);
|
||||
}
|
||||
|
||||
if (i % 2)
|
||||
m_arrayData[i >> 1] |= static_cast<signed char>(nibbleIntValue << 4);
|
||||
else
|
||||
m_arrayData[i >> 1] |= static_cast<signed char>(nibbleIntValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
std::string BitArray::getDebugString() const
|
||||
{
|
||||
std::string s = FormattedString<512>().sprintf("%6d: ", m_numInUseBits);
|
||||
int i;
|
||||
for (i = 0; i < m_numInUseBits; ++i)
|
||||
{
|
||||
if ((i > 0) && ((i % 8) == 0))
|
||||
s += " ";
|
||||
|
||||
if (testBit(i))
|
||||
s += "1";
|
||||
else
|
||||
s += "0";
|
||||
}
|
||||
|
||||
s += " (";
|
||||
|
||||
std::string baString;
|
||||
getAsDbTextString(baString);
|
||||
s += baString;
|
||||
|
||||
s += ") (";
|
||||
|
||||
for (int i = 0; i < m_numAllocatedBytes; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
s += " ";
|
||||
|
||||
if (i == m_numInUseBytes)
|
||||
s += " ";
|
||||
|
||||
s += FormattedString<512>().sprintf("%02X", static_cast<unsigned char>(m_arrayData[i]));
|
||||
}
|
||||
|
||||
s += ")";
|
||||
|
||||
if (m_arrayData == m_defaultData)
|
||||
s += FormattedString<512>().sprintf(" (%d/%d default storage)", m_numInUseBytes, m_numAllocatedBytes);
|
||||
else
|
||||
s += FormattedString<512>().sprintf(" (%d/%d heap storage)", m_numInUseBytes, m_numAllocatedBytes);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,111 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// BitArray.h
|
||||
// Copyright 2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_BitArray_H
|
||||
#define INCLUDED_BitArray_H
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BitArray;
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
class ReadIterator;
|
||||
class ByteStream;
|
||||
|
||||
void get (ReadIterator &source, BitArray &target);
|
||||
void put (ByteStream &target, const BitArray &source);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BitArray
|
||||
{
|
||||
public:
|
||||
BitArray ();
|
||||
explicit BitArray (int numBits);
|
||||
BitArray (const BitArray&);
|
||||
virtual ~BitArray ();
|
||||
|
||||
void setBit (int index);
|
||||
void setValue (int beginIndex, int endIndex, unsigned long value);
|
||||
void setMultipleBits(int count);
|
||||
void clearBit (int index);
|
||||
bool testBit (int index) const;
|
||||
unsigned long getValue (int beginIndex, int endIndex) const;
|
||||
void clear();
|
||||
int getNumberOfSetBits() const;
|
||||
bool empty() const;
|
||||
void insertBit(int const index, bool value);
|
||||
void removeBit(int const index);
|
||||
std::string getDebugString() const;
|
||||
|
||||
// Equivalent to operator==()
|
||||
bool match (const BitArray &rhs) const;
|
||||
|
||||
// Returns true if array has any bits set which this array also has set.
|
||||
bool matchAnyBit (const BitArray &rhs) const;
|
||||
|
||||
//operators
|
||||
BitArray & operator = (const BitArray &rhs);
|
||||
bool operator == (const BitArray &rhs) const;
|
||||
bool operator!= (const BitArray &rhs) const;
|
||||
|
||||
// for DB persistence purpose, returns the BitArray as a
|
||||
// std::string where each 4 bits are printed as a hex nibble;
|
||||
// and the converse that takes the null-terminated string
|
||||
// and converts it back into the BitArray
|
||||
void getAsDbTextString(std::string &result, int maxNibbleCount = 32767) const;
|
||||
void setFromDbTextString(const char * text);
|
||||
|
||||
friend void Archive::get (ReadIterator &source, BitArray &target);
|
||||
friend void Archive::put (ByteStream &target, const BitArray &source);
|
||||
|
||||
private:
|
||||
// *****WARNING***** *****WARNING***** *****WARNING***** *****WARNING*****
|
||||
// do not expose the "size" (either m_numInUseBits, m_numInUseBytes, or
|
||||
// m_numAllocatedBytes) to the outside world, since it is not guaranteed
|
||||
// to be accurate in terms of what the outside world expects the "size"
|
||||
// to be; for optimization, BitArray doesn't necessarily change the "size"
|
||||
// value(s) if a particular bit index is not set; for example, if you do
|
||||
// setBit(1000000), and then do clearBit(1000000), the "size" is not
|
||||
// necessarily 1000000; the only guarantee we make here is that
|
||||
// testBit(1000000) will return false; the bottom line is that BitArray
|
||||
// does not maintain the "size" of the BitArray, so no function should
|
||||
// ever be added to return the "size" of the BitArray
|
||||
// *****WARNING***** *****WARNING***** *****WARNING***** *****WARNING*****
|
||||
|
||||
// to avoid constant reallocation for small BitArray, small BitArray will
|
||||
// use this as storage; only when the BitArray is larger than 128 (16*8)
|
||||
// will we need to allocate off the heap
|
||||
signed char m_defaultData[16];
|
||||
|
||||
// points to the storage for the BitArray, which will be either m_defaultData
|
||||
// or heap allocated storage for BitArray larger than 128 (16*8)
|
||||
signed char *m_arrayData;
|
||||
|
||||
// how many chars allocated in m_arrayData
|
||||
int m_numAllocatedBytes;
|
||||
|
||||
// how many chars in m_arrayData that's actually used for the BitArray;
|
||||
// this will always be <= m_numAllocatedBytes;
|
||||
// this will always be 0 or (m_numInUseBits+7) >> 3, but we cache it here
|
||||
// so we don't constantly have to calculate (m_numInUseBits+7) >> 3
|
||||
int m_numInUseBytes;
|
||||
|
||||
// storage (i.e. m_arrayData) may be allocated to handle more than m_numInUseBits,
|
||||
// because its expensive to be constantly expanding and shrinking m_arrayData;
|
||||
// however, every bit past 0-based index (m_numInUseBits - 1) is guaranteed to be unset
|
||||
int m_numInUseBits;
|
||||
|
||||
void reserve (int numBits);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Branch.cpp
|
||||
//
|
||||
// copyright 2005 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Branch.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
namespace BranchNamespace
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const char * cs_win32PathSeperator = "\\";
|
||||
#endif
|
||||
const char * cs_pathSeperator = "/";
|
||||
const char * cs_branchIdentifierString = "/src/engine/shared";
|
||||
}
|
||||
|
||||
using namespace BranchNamespace;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
Branch::Branch()
|
||||
{
|
||||
m_branchName = __FILE__;
|
||||
|
||||
std::string::size_type slash = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
while ( ( slash = m_branchName.find( cs_win32PathSeperator, slash ) ) != std::string::npos )
|
||||
{
|
||||
m_branchName[ slash ] = *cs_pathSeperator;
|
||||
}
|
||||
#endif
|
||||
|
||||
slash = m_branchName.find( cs_branchIdentifierString );
|
||||
|
||||
if ( slash != std::string::npos )
|
||||
{
|
||||
m_branchName.resize( slash );
|
||||
|
||||
slash = m_branchName.rfind( cs_pathSeperator );
|
||||
|
||||
if ( slash != std::string::npos )
|
||||
{
|
||||
m_branchName = m_branchName.substr( ++slash );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
const std::string & Branch::getBranchName() const
|
||||
{
|
||||
return m_branchName;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@@ -0,0 +1,26 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Branch.h
|
||||
// copyright 2005 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Branch_H
|
||||
#define INCLUDED_Branch_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class Branch
|
||||
{
|
||||
public:
|
||||
Branch();
|
||||
|
||||
const std::string & getBranchName() const;
|
||||
|
||||
private:
|
||||
std::string m_branchName;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,398 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CalendarTime.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/CalendarTime.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
std::string CalendarTime::convertEpochToTimeStringGMT(time_t epoch)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
struct tm * timeinfo = ::gmtime(&epoch);
|
||||
if (timeinfo == NULL)
|
||||
return result;
|
||||
|
||||
char * asciiTime = ::asctime(timeinfo);
|
||||
if (asciiTime == NULL)
|
||||
return result;
|
||||
|
||||
static char resultBuffer[512];
|
||||
char * buffer = resultBuffer;
|
||||
if (strlen(asciiTime) >= sizeof(resultBuffer))
|
||||
buffer = new char[strlen(asciiTime) + 1];
|
||||
|
||||
strcpy(buffer, asciiTime);
|
||||
buffer[strcspn(buffer, "\r\n")] = '\0';
|
||||
result = buffer;
|
||||
|
||||
if (buffer != resultBuffer)
|
||||
delete[] buffer;
|
||||
|
||||
result += " GMT";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
std::string CalendarTime::convertEpochToTimeStringGMT_YYYYMMDDHHMMSS(time_t epoch)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
struct tm * timeinfo = ::gmtime(&epoch);
|
||||
if (timeinfo == NULL)
|
||||
return result;
|
||||
|
||||
static char resultBuffer[512];
|
||||
snprintf(resultBuffer, sizeof(resultBuffer), "%d-%02d-%02d %02d:%02d:%02d GMT", (timeinfo->tm_year + 1900), (timeinfo->tm_mon + 1), timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||
|
||||
return std::string(resultBuffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string CalendarTime::convertEpochToTimeStringLocal(time_t epoch)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
struct tm * timeinfo = ::localtime(&epoch);
|
||||
if (timeinfo == NULL)
|
||||
return result;
|
||||
|
||||
char * asciiTime = ::asctime(timeinfo);
|
||||
if (asciiTime == NULL)
|
||||
return result;
|
||||
|
||||
static char resultBuffer[512];
|
||||
char * buffer = resultBuffer;
|
||||
if (strlen(asciiTime) >= sizeof(resultBuffer))
|
||||
buffer = new char[strlen(asciiTime) + 1];
|
||||
|
||||
strcpy(buffer, asciiTime);
|
||||
buffer[strcspn(buffer, "\r\n")] = '\0';
|
||||
result = buffer;
|
||||
|
||||
if (buffer != resultBuffer)
|
||||
delete[] buffer;
|
||||
|
||||
// get local time zone string
|
||||
static char buffer2[256];
|
||||
if (0 < ::strftime(buffer2, sizeof(buffer2)-1, "%Z", timeinfo))
|
||||
{
|
||||
result += " ";
|
||||
result += buffer2;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += " local";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string CalendarTime::convertEpochToTimeStringLocal_YYYYMMDDHHMMSS(time_t epoch)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
struct tm * timeinfo = ::localtime(&epoch);
|
||||
if (timeinfo == NULL)
|
||||
return result;
|
||||
|
||||
static char resultBuffer[512];
|
||||
snprintf(resultBuffer, sizeof(resultBuffer), "%d-%02d-%02d %02d:%02d:%02d ", (timeinfo->tm_year + 1900), (timeinfo->tm_mon + 1), timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||
|
||||
result = resultBuffer;
|
||||
|
||||
if (0 < ::strftime(resultBuffer, sizeof(resultBuffer)-1, "%Z", timeinfo))
|
||||
{
|
||||
result += resultBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += "local";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string CalendarTime::convertSecondsToDHMS(unsigned int numSeconds)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
snprintf(buffer, sizeof(buffer)-1, "%ud:%uh:%um:%us",
|
||||
numSeconds / (60 * 60 * 24),
|
||||
(numSeconds % (60 * 60 * 24)) / (60 * 60),
|
||||
(numSeconds % (60 * 60)) / 60,
|
||||
numSeconds % 60);
|
||||
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string CalendarTime::convertSecondsToHMS(unsigned int numSeconds)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
snprintf(buffer, sizeof(buffer)-1, "%uh:%um:%us",
|
||||
numSeconds / (60 * 60),
|
||||
(numSeconds % (60 * 60)) / 60,
|
||||
numSeconds % 60);
|
||||
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string CalendarTime::convertSecondsToMS(unsigned int numSeconds)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
snprintf(buffer, sizeof(buffer)-1, "%um:%us",
|
||||
numSeconds / 60,
|
||||
numSeconds % 60);
|
||||
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// given a starting Epoch GMT time, returns the Epoch GMT time when the next specified
|
||||
// GMT day of week, hour, minute, and second will occur; note that the day of week, hour,
|
||||
// minute, and second specified will all be interpreted in terms of GMT time
|
||||
//
|
||||
// returns -1 if invalid parameters are specified or there are any system errors
|
||||
// in making the calculation
|
||||
//
|
||||
// day of week is 0=Sunday, 1=Monday, 2=Tuesday, 3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday
|
||||
// if you just want to find out when the next hour, minute, second will occur, specify -1 for
|
||||
// day of week
|
||||
//
|
||||
// hour must be between 0-23
|
||||
// if you just want to find out when the next minute, second will occur, specify -1 for day
|
||||
// of week and -1 for hour
|
||||
//
|
||||
// minute must be between 0-59
|
||||
//
|
||||
// second must be between 0-59
|
||||
|
||||
time_t CalendarTime::getNextGMTTimeOcurrence(time_t const startTime, int const dayOfWeek, int const hour, int const minute, int const second)
|
||||
{
|
||||
// don't allow start time to be too far in the past
|
||||
if (startTime < CalendarTimeNamespace::g_CalendarTimeEarliestTime)
|
||||
return -1;
|
||||
|
||||
if ((dayOfWeek < -1) || (dayOfWeek > 6))
|
||||
return -1;
|
||||
|
||||
if ((hour < -1) || (hour > 23))
|
||||
return -1;
|
||||
|
||||
if ((hour == -1) && (dayOfWeek != -1))
|
||||
return -1;
|
||||
|
||||
if ((minute < 0) || (minute > 59))
|
||||
return -1;
|
||||
|
||||
if ((second < 0) || (second > 59))
|
||||
return -1;
|
||||
|
||||
// convert the start time into a broken down time containing
|
||||
// the year, month, day, day of week, hour, minute, second
|
||||
// in GMT time
|
||||
struct tm * timeinfo = ::gmtime(&startTime);
|
||||
if (timeinfo == NULL)
|
||||
return -1;
|
||||
|
||||
// get number of days until the specified day of week to search for
|
||||
if (dayOfWeek >= 0)
|
||||
{
|
||||
int daysUntil = 0;
|
||||
|
||||
// calculate the Epoch GMT time for the specified start time
|
||||
// at the specified hour, minute, and second
|
||||
time_t startTimeAtSpecifiedHourMinuteSecond = startTime + (((hour * 60 * 60) + (minute * 60) + second) - ((timeinfo->tm_hour * 60 * 60) + (timeinfo->tm_min * 60) + timeinfo->tm_sec));
|
||||
|
||||
if (timeinfo->tm_wday != dayOfWeek)
|
||||
{
|
||||
if (timeinfo->tm_wday < dayOfWeek)
|
||||
daysUntil = dayOfWeek - timeinfo->tm_wday;
|
||||
else
|
||||
// wraparound
|
||||
daysUntil = (6 - timeinfo->tm_wday) + dayOfWeek + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the specified day of week matches the start day of week, but
|
||||
// the specified time has already passed, then we want go forward
|
||||
// to next week
|
||||
if (startTimeAtSpecifiedHourMinuteSecond <= startTime)
|
||||
daysUntil = 7;
|
||||
}
|
||||
|
||||
// the next time the that the day/time will match
|
||||
startTimeAtSpecifiedHourMinuteSecond += (60 * 60 * 24 * daysUntil);
|
||||
|
||||
return startTimeAtSpecifiedHourMinuteSecond;
|
||||
}
|
||||
|
||||
// dayOfWeek == -1
|
||||
if (hour >= 0)
|
||||
{
|
||||
// calculate the Epoch GMT time for the specified start time
|
||||
// at the specified hour, minute, and second
|
||||
time_t startTimeAtSpecifiedHourMinuteSecond = startTime + (((hour * 60 * 60) + (minute * 60) + second) - ((timeinfo->tm_hour * 60 * 60) + (timeinfo->tm_min * 60) + timeinfo->tm_sec));
|
||||
|
||||
// no day of week specified, we want when the time will
|
||||
// match on the day of the start time, or if the time has
|
||||
// already passed for the day of the start time, then we
|
||||
// when the time will match for the day following the day
|
||||
// of the start time
|
||||
if (startTimeAtSpecifiedHourMinuteSecond <= startTime)
|
||||
startTimeAtSpecifiedHourMinuteSecond += (60 * 60 * 24);
|
||||
|
||||
return startTimeAtSpecifiedHourMinuteSecond;
|
||||
}
|
||||
|
||||
// dayOfWeek == -1 and hour == -1
|
||||
time_t startTimeAtSpecifiedHourMinuteSecond = startTime + (((minute * 60) + second) - ((timeinfo->tm_min * 60) + timeinfo->tm_sec));
|
||||
|
||||
// no day of week or hour specified, we want when the minute:second
|
||||
// will match on the hour of the start time, or if the minute:second
|
||||
// has already passed for the hour of the start time, then we want
|
||||
// when the minute:second will match for the hour following the
|
||||
// hour of the start time
|
||||
if (startTimeAtSpecifiedHourMinuteSecond <= startTime)
|
||||
startTimeAtSpecifiedHourMinuteSecond += (60 * 60);
|
||||
|
||||
return startTimeAtSpecifiedHourMinuteSecond;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// given a starting Epoch GMT time, returns the Epoch GMT time when the next specified
|
||||
// GMT month, day of month, hour, minute, and second will occur; note that the month,
|
||||
// day of month, hour, minute, and second specified will all be interpreted in terms
|
||||
// of GMT time
|
||||
//
|
||||
// returns -1 if invalid parameters are specified or there are any system errors
|
||||
// in making the calculation
|
||||
//
|
||||
// month must be between 1-12
|
||||
// if you just want to find out when the next day of month, hour, minute, and second will occur,
|
||||
// specify -1 for month
|
||||
//
|
||||
// dayOfMonth must be between 1-31
|
||||
//
|
||||
// hour must be between 0-23
|
||||
//
|
||||
// minute must be between 0-59
|
||||
//
|
||||
// second must be between 0-59
|
||||
time_t CalendarTime::getNextGMTTimeOcurrence(time_t const startTime, int const month, int const dayOfMonth, int const hour, int const minute, int const second)
|
||||
{
|
||||
// don't allow start time to be too far in the past
|
||||
if (startTime < CalendarTimeNamespace::g_CalendarTimeEarliestTime)
|
||||
return -1;
|
||||
|
||||
if (month == 0)
|
||||
return -1;
|
||||
|
||||
if ((month < -1) || (month > 12))
|
||||
return -1;
|
||||
|
||||
if ((dayOfMonth < 1) || (dayOfMonth > 31))
|
||||
return -1;
|
||||
|
||||
if ((hour < 0) || (hour > 23))
|
||||
return -1;
|
||||
|
||||
if ((minute < 0) || (minute > 59))
|
||||
return -1;
|
||||
|
||||
if ((second < 0) || (second > 59))
|
||||
return -1;
|
||||
|
||||
// convert the start time into a broken down time containing
|
||||
// the year, month, day, day of week, hour, minute, second
|
||||
// in GMT time
|
||||
struct tm * timeinfo = ::gmtime(&startTime);
|
||||
if (timeinfo == NULL)
|
||||
return -1;
|
||||
|
||||
// calculate the Epoch GMT time for the specified start time
|
||||
// at the specified hour, minute, and second
|
||||
time_t startTimeAtSpecifiedHourMinuteSecond = startTime + (((hour * 60 * 60) + (minute * 60) + second) - ((timeinfo->tm_hour * 60 * 60) + (timeinfo->tm_min * 60) + timeinfo->tm_sec));
|
||||
|
||||
// timeinfo uses 0-based month
|
||||
int const targetMonth = ((month == -1) ? -1 : (month - 1));
|
||||
|
||||
// to catch infinite loop caused by stuff like "April 31", but
|
||||
// make sure we loop long enough to include the next leap day "February 29"
|
||||
int const maxIterations = (((month == 2) && (dayOfMonth == 29)) ? (365*4+1) : (365+1));
|
||||
int sentinel = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (((targetMonth == -1) || (targetMonth == timeinfo->tm_mon)) && (dayOfMonth == timeinfo->tm_mday) && (startTimeAtSpecifiedHourMinuteSecond > startTime))
|
||||
break;
|
||||
|
||||
// start adding 1 day at a time until the target month and day of month is reached
|
||||
// TODO: find a better way of doing this rather than looping 1 day at a time
|
||||
startTimeAtSpecifiedHourMinuteSecond += (60 * 60 * 24);
|
||||
|
||||
timeinfo = ::gmtime(&startTimeAtSpecifiedHourMinuteSecond);
|
||||
if (timeinfo == NULL)
|
||||
return -1;
|
||||
|
||||
if (++sentinel > maxIterations)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return startTimeAtSpecifiedHourMinuteSecond;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
std::string CalendarTime::getCharacerBirthDateString(int characterBirthDate)
|
||||
{
|
||||
// the birth date (for characters created on live and TC clusters) is the
|
||||
// number of days since 00:00:00 Jan 1st, 2001 PST
|
||||
// (see the server's PlayerObject::getCurrentBornDate())
|
||||
// 978336000 is the epoch value corresponding to 00:00:00 Jan 1st, 2001 PST
|
||||
time_t const baseTime = 978336000 + static_cast<time_t>(characterBirthDate * 60 * 60 * 24) - (60 * 60 * 12);
|
||||
|
||||
struct tm const * const birthDateTimeData = ::localtime(&baseTime);
|
||||
|
||||
// get local time zone string
|
||||
std::string timeZone("local");
|
||||
|
||||
char buffer[256];
|
||||
if (0 < ::strftime(buffer, sizeof(buffer)-1, "%Z", birthDateTimeData))
|
||||
{
|
||||
timeZone = buffer;
|
||||
}
|
||||
|
||||
snprintf(buffer, sizeof(buffer)-1, "%02d %02d %d %s", (birthDateTimeData->tm_mon + 1), birthDateTimeData->tm_mday, (birthDateTimeData->tm_year + 1900), timeZone.c_str());
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,42 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CalendarTime.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CalendarTime_H
|
||||
#define INCLUDED_CalendarTime_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// Sat Jan 01 00:00:00 1980 (just an arbitrary value)
|
||||
namespace CalendarTimeNamespace
|
||||
{
|
||||
const time_t g_CalendarTimeEarliestTime = 315550800;
|
||||
};
|
||||
|
||||
class CalendarTime
|
||||
{
|
||||
private:
|
||||
|
||||
CalendarTime(void);
|
||||
CalendarTime(const CalendarTime &);
|
||||
CalendarTime &operator =(const CalendarTime &);
|
||||
|
||||
public:
|
||||
|
||||
static std::string convertEpochToTimeStringGMT(time_t epoch);
|
||||
static std::string convertEpochToTimeStringGMT_YYYYMMDDHHMMSS(time_t epoch);
|
||||
static std::string convertEpochToTimeStringLocal(time_t epoch);
|
||||
static std::string convertEpochToTimeStringLocal_YYYYMMDDHHMMSS(time_t epoch);
|
||||
static std::string convertSecondsToDHMS(unsigned int numSeconds);
|
||||
static std::string convertSecondsToHMS(unsigned int numSeconds);
|
||||
static std::string convertSecondsToMS(unsigned int numSeconds);
|
||||
static time_t getNextGMTTimeOcurrence(time_t startTime, int dayOfWeek, int hour, int minute, int second);
|
||||
static time_t getNextGMTTimeOcurrence(time_t startTime, int month, int dayOfMonth, int hour, int minute, int second);
|
||||
|
||||
static std::string getCharacerBirthDateString(int characterBirthDate);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
// CallbackEntryBase.h
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_CallbackEntryBase_H
|
||||
#define _INCLUDED_CallbackEntryBase_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class Scheduler;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @brief Internally used class that identifies callbacks.
|
||||
|
||||
@see CallbackEntry
|
||||
@see StaticCallbackEntry
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
class CallbackEntryBase
|
||||
{
|
||||
protected:
|
||||
CallbackEntryBase(const unsigned long when);
|
||||
virtual ~CallbackEntryBase() = 0;
|
||||
|
||||
public:
|
||||
virtual void expired() = 0;
|
||||
const unsigned long getExpireCount() const;
|
||||
|
||||
/** @brief Compare functor supplied for use with a priority queue.
|
||||
*/
|
||||
struct Compare
|
||||
{
|
||||
bool operator ()(const CallbackEntryBase * lhs, const CallbackEntryBase * rhs) const
|
||||
{
|
||||
return lhs->expireCount > rhs->expireCount;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
friend struct Compare;
|
||||
|
||||
unsigned long expireCount;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @return the expiration count ("time", "frame", whatever) of the callback.
|
||||
*/
|
||||
inline const unsigned long CallbackEntryBase::getExpireCount() const
|
||||
{
|
||||
return expireCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_CallbackEntryBase_H
|
||||
@@ -0,0 +1,528 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Clock.cpp
|
||||
//
|
||||
// Portions copyright 1998 Bootprint Entertainment
|
||||
// Portsion copyright 2002 Sony Online Entertainment
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Clock.h"
|
||||
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedDebug/DebugFlags.h"
|
||||
#include "sharedDebug/Profiler.h"
|
||||
#include "sharedFile/TreeFile.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/Production.h"
|
||||
#include "sharedDebug/RemoteDebug.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
#include "sharedThread/RunThread.h"
|
||||
#include "sharedThread/ThreadHandle.h"
|
||||
#include <string>
|
||||
|
||||
#ifdef PLATFORM_WIN32 //@todo code reorg
|
||||
#include "sharedFoundation/WindowsWrapper.h"
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
real Clock::ms_lastFrameRate;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace ClockNamespace
|
||||
{
|
||||
__int64 ms_lastPoll; // the last time the clock was polled at the start of a frame
|
||||
real ms_lastFrameTime; // the time (in seconds) that the last frame took
|
||||
real ms_maxFrameTime; // the maximum time a frame is allowed to be. If exceeded, a warning is logged.
|
||||
unsigned long ms_applicationStartTime; // the time the application was started
|
||||
double ms_realTimeMilliseconds;
|
||||
bool ms_useSleep;
|
||||
#if PRODUCTION == 0
|
||||
bool ms_debugReportFlag;
|
||||
bool ms_debugReportLogFlag;
|
||||
#endif
|
||||
bool ms_debugReportLongFrames;
|
||||
int ms_previousNumberOfFilesOpenedTotal;
|
||||
int ms_previousSizeOfFilesOpenedTotal;
|
||||
int ms_timeZone;
|
||||
ThreadHandle ms_threadHandle;
|
||||
Mutex ms_mutex;
|
||||
Semaphore ms_shutdownEvent;
|
||||
bool ms_shutdown = false;
|
||||
unsigned int const ms_recalibrationInterval = 1000;
|
||||
unsigned int const ms_recalibrationMultiplier = 1000 / ms_recalibrationInterval;
|
||||
real ms_realFrequency; // periodically calibrated clock frequency, updated from clock thread
|
||||
real ms_frameFrequency; // clock frequency being used during the current frame, updated from realFrequency each frame
|
||||
real ms_frameRateLimit;
|
||||
|
||||
static const double cms_secondsPerMillisecond = 0.001;
|
||||
|
||||
#if PRODUCTION == 0
|
||||
static void reportMinimumFrameTime();
|
||||
|
||||
bool ms_reportMinimumFrameTime;
|
||||
bool ms_resetMinimumFrameTime;
|
||||
float ms_minimumFrameTime;
|
||||
bool ms_useRecalibrationThread;
|
||||
bool ms_lastUseRecalibrationThread;
|
||||
#endif
|
||||
|
||||
bool ms_longFramesWarningAllowed = true;
|
||||
|
||||
void threadRoutine();
|
||||
}
|
||||
using namespace ClockNamespace;
|
||||
|
||||
// ======================================================================
|
||||
// Install the Clock subsystem
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// The Clock currently requires the use of the high performance counter in Windows.
|
||||
// If the high performance counter is unavailable, this routine will call Fatal.
|
||||
//
|
||||
// This routine will also add Clock::remove to the ExitChain.
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// Clock::remove()
|
||||
|
||||
void Clock::install(bool newUseSleep, bool useRecalibrationThread)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
ms_useSleep = newUseSleep;
|
||||
|
||||
#if PRODUCTION == 0
|
||||
ms_useRecalibrationThread = useRecalibrationThread;
|
||||
ms_lastUseRecalibrationThread = useRecalibrationThread;
|
||||
#endif
|
||||
|
||||
ExitChain::add(Clock::remove, "Clock::remove");
|
||||
|
||||
__int64 frequency;
|
||||
result = QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&frequency));
|
||||
FATAL(!result, ("Clock::install QPF failed"));
|
||||
|
||||
result = QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&ms_lastPoll));
|
||||
FATAL(!result, ("Clock::install QPC failed"));
|
||||
|
||||
ms_realFrequency = static_cast<real>(frequency);
|
||||
ms_frameFrequency = ms_realFrequency;
|
||||
|
||||
if (ConfigSharedFoundation::getFrameRateLimit() != 0.0f)
|
||||
setFrameRateLimit(ConfigSharedFoundation::getFrameRateLimit());
|
||||
setMinFrameRate(ConfigSharedFoundation::getMinFrameRate());
|
||||
|
||||
#if PRODUCTION == 0
|
||||
DebugFlags::registerFlag(ms_debugReportFlag, "SharedFoundation", "reportClock", debugReport, -1000);
|
||||
DebugFlags::registerFlag(ms_reportMinimumFrameTime, "SharedFoundation", "reportMinimumFrameTime", reportMinimumFrameTime, -990);
|
||||
DebugFlags::registerFlag(ms_resetMinimumFrameTime, "SharedFoundation", "resetMinimumFrameTime");
|
||||
DebugFlags::registerFlag(ms_debugReportLogFlag, "SharedFoundation", "logClock");
|
||||
DebugFlags::registerFlag(ms_debugReportLongFrames, "SharedFoundation", "debugReportLongFrames");
|
||||
DebugFlags::registerFlag(ms_useRecalibrationThread, "SharedFoundation", "useClockRecalibrationThread");
|
||||
#endif
|
||||
|
||||
time_t t = 0;
|
||||
localtime(&t);
|
||||
ms_timeZone = timezone;
|
||||
if(ms_timeZone < (12 * 60 * 60))
|
||||
{
|
||||
ms_timeZone = -ms_timeZone;
|
||||
}
|
||||
ms_realTimeMilliseconds = static_cast<double>(ms_lastPoll / ms_frameFrequency * 1000.f);
|
||||
ms_applicationStartTime = timeSeconds();
|
||||
|
||||
if (useRecalibrationThread)
|
||||
{
|
||||
ms_shutdown = false;
|
||||
ms_threadHandle = runNamedThread("Clock", threadRoutine);
|
||||
ms_threadHandle->setPriority(Thread::kCritical);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Remove the clock subsystem.
|
||||
*
|
||||
* This routine should not be called directly by users. Clock::install() will add
|
||||
* this routine onto the ExitChain.
|
||||
*
|
||||
* @see Clock::install()
|
||||
*/
|
||||
|
||||
void Clock::remove(void)
|
||||
{
|
||||
#if PRODUCTION == 0
|
||||
DebugFlags::unregisterFlag(ms_debugReportFlag);
|
||||
DebugFlags::unregisterFlag(ms_debugReportLogFlag);
|
||||
DebugFlags::unregisterFlag(ms_debugReportLongFrames);
|
||||
#endif
|
||||
|
||||
if (ms_threadHandle)
|
||||
{
|
||||
ms_mutex.enter();
|
||||
ms_shutdown = true;
|
||||
ms_mutex.leave();
|
||||
ms_shutdownEvent.signal();
|
||||
ms_threadHandle->wait();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Update the clock.
|
||||
*
|
||||
* This routine will recompute the amount of time the last frame took to complete.
|
||||
* If this routine is not called, the values returned by Clock::frameTime() and
|
||||
* Clock::framesPerSecond() will not change.
|
||||
*
|
||||
* @see Clock::frameTime(), Clock::framesPerSecond()
|
||||
*/
|
||||
|
||||
void Clock::update(void)
|
||||
{
|
||||
__int64 newPoll;
|
||||
BOOL result;
|
||||
|
||||
#if PRODUCTION == 0
|
||||
if (ms_lastUseRecalibrationThread != ms_useRecalibrationThread)
|
||||
{
|
||||
if (ms_useRecalibrationThread)
|
||||
{
|
||||
ms_shutdown = false;
|
||||
ms_threadHandle = runNamedThread("Clock", threadRoutine);
|
||||
ms_threadHandle->setPriority(Thread::kCritical);
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_mutex.enter();
|
||||
ms_shutdown = true;
|
||||
ms_mutex.leave();
|
||||
ms_shutdownEvent.signal();
|
||||
ms_threadHandle->wait();
|
||||
}
|
||||
ms_lastUseRecalibrationThread = ms_useRecalibrationThread;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&newPoll));
|
||||
FATAL(!result, ("Clock::update QPC failed"));
|
||||
|
||||
// We need to consider time before this frame as having passed with a
|
||||
// potentially different frequency, and also need to consider portions
|
||||
// of a millisecond.
|
||||
|
||||
real const frameTime = static_cast<real>(newPoll - ms_lastPoll) / ms_frameFrequency;
|
||||
ms_realTimeMilliseconds += static_cast<double>(frameTime*1000.f);
|
||||
|
||||
ms_mutex.enter();
|
||||
ms_frameFrequency = ms_realFrequency;
|
||||
ms_mutex.leave();
|
||||
|
||||
if (!Os::wasFocusLost())
|
||||
{
|
||||
ms_lastFrameTime = frameTime;
|
||||
|
||||
#if PRODUCTION == 0
|
||||
float const debugReportLongFrameTime = ConfigSharedFoundation::getDebugReportLongFrameTime();
|
||||
if (ms_debugReportLongFrames && ms_lastFrameTime > debugReportLongFrameTime)
|
||||
{
|
||||
REPORT_LOG(true, ("------------------------------------------------\n"));
|
||||
REPORT_LOG(true, ("WARNING: Clock::update[%d] Last Frame took %f seconds\n", Os::getNumberOfUpdates(), ms_lastFrameTime));
|
||||
REPORT_LOG(true, ("Files: %4d opened, %4d KB\n", TreeFile::getNumberOfFilesOpenedTotal() - ms_previousNumberOfFilesOpenedTotal, (TreeFile::getSizeOfFilesOpenedTotal() - ms_previousSizeOfFilesOpenedTotal) / 1024));
|
||||
Profiler::setTemporaryExpandAll(true);
|
||||
Profiler::printLastFrameData();
|
||||
REPORT_LOG(true, ("%s\n", Profiler::getLastFrameData()));
|
||||
Profiler::setTemporaryExpandAll(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ms_lastFrameTime > ms_maxFrameTime)
|
||||
{
|
||||
DEBUG_REPORT_LOG(ms_longFramesWarningAllowed, ("WARNING: Clock::update[%d] Last Frame took %f seconds\n", Os::getNumberOfUpdates(), ms_lastFrameTime));
|
||||
ms_lastFrameTime = ms_maxFrameTime;
|
||||
}
|
||||
|
||||
ms_lastFrameRate = RECIP(ms_lastFrameTime);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// -qq- debugging W2K QueryPerformanceCounter
|
||||
static DWORD lastTick;
|
||||
DWORD newTick = GetTickCount();
|
||||
|
||||
DEBUG_REPORT_LOG_PRINT(true, ("Clock::update %I64d %I64d %6I64d %10d %10d %3d %6.2f=fps %6.4f=time\n", ms_lastPoll, newPoll, newPoll - ms_lastPoll, lastTick, newTick, newTick - lastTick, ms_lastFrameRate, ms_lastFrameTime));
|
||||
|
||||
static int bad = 0;
|
||||
|
||||
if (bad && ++bad > 64)
|
||||
__asm int 3;
|
||||
|
||||
if (ms_lastFrameTime > 3.0)
|
||||
bad = 1;
|
||||
|
||||
lastTick = newTick;
|
||||
#endif
|
||||
|
||||
ms_lastPoll = newPoll;
|
||||
|
||||
|
||||
#if PRODUCTION == 0
|
||||
ms_previousNumberOfFilesOpenedTotal = TreeFile::getNumberOfFilesOpenedTotal();
|
||||
ms_previousSizeOfFilesOpenedTotal = TreeFile::getSizeOfFilesOpenedTotal();
|
||||
|
||||
if (ms_resetMinimumFrameTime || ms_lastFrameTime < ms_minimumFrameTime)
|
||||
{
|
||||
ms_resetMinimumFrameTime = false;
|
||||
ms_minimumFrameTime = ms_lastFrameTime;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Display debugging information for the clock.
|
||||
*/
|
||||
|
||||
void Clock::debugReport(void)
|
||||
{
|
||||
#if PRODUCTION == 0
|
||||
REPORT(true, Report::RF_print | (ms_debugReportLogFlag ? Report::RF_log : 0), ("Clock %6.2f=fps %8.6f=time\n", ms_lastFrameRate, ms_lastFrameTime));
|
||||
DEBUG_OUTPUT_STATIC_VIEW_BEGINFRAME("Foundation\\Clock");
|
||||
DEBUG_OUTPUT_STATIC_VIEW("Foundation\\Clock", ("Clock %6.2f=fps %6.4f=time\n", ms_lastFrameRate, ms_lastFrameTime));
|
||||
DEBUG_OUTPUT_STATIC_VIEW_ENDFRAME("Foundation\\Clock");
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#if PRODUCTION == 0
|
||||
|
||||
void ClockNamespace::reportMinimumFrameTime(void)
|
||||
{
|
||||
REPORT(true, Report::RF_print, ("min frame time %8.6f\n", ms_minimumFrameTime));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Get the amount of time the last frame took
|
||||
//
|
||||
// Return Value:
|
||||
//
|
||||
// Time, in seconds, for the last frame
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine currently does not take in to account if the game was
|
||||
// task-switched out of.
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// Clock::framesPerSecond()
|
||||
|
||||
real Clock::frameTime(void)
|
||||
{
|
||||
return ms_lastFrameTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Disable the frame rate limiter.
|
||||
*
|
||||
* Calling this routine will make the Clock subsystem allow the game to run at
|
||||
* the fastest rate possible.
|
||||
*
|
||||
* @see Clock::setFrameRateLimit()
|
||||
*/
|
||||
|
||||
void Clock::noFrameRateLimit(void)
|
||||
{
|
||||
ms_frameRateLimit = 0.f;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Enable the frame rate limiter to a specific frame rate value.
|
||||
*
|
||||
* This routine will set the maximum number of frame-per-second that the game
|
||||
* will be allowed to run. If the game could run faster than that, the Clock
|
||||
* subsystem will wait when Clock::limitFrameRate() is called.
|
||||
*
|
||||
* @param newFrameRateLimit Frames per second for the clock to limit the game to
|
||||
* @see Clock::noFrameRateLimit(), Clock::limitFrameRate()
|
||||
*/
|
||||
|
||||
void Clock::setFrameRateLimit(real newFrameRateLimit)
|
||||
{
|
||||
DEBUG_FATAL(newFrameRateLimit < 1.0f, ("Clock::setFrameRateLimit can not be under 1, %f", newFrameRateLimit));
|
||||
ms_frameRateLimit = newFrameRateLimit;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set a minimum frame rate for the game.
|
||||
*
|
||||
* This routine sets a minimum frame rate for the game. Any frames that take longer will
|
||||
* log a warning then have the next frame time set to the given minimum value.
|
||||
*
|
||||
*/
|
||||
|
||||
void Clock::setMinFrameRate(real newMinFrameRate)
|
||||
{
|
||||
if (newMinFrameRate == 0)
|
||||
ms_maxFrameTime = REAL_MAX;
|
||||
else
|
||||
ms_maxFrameTime = RECIP(newMinFrameRate);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Wait if the game is running too fast.
|
||||
*
|
||||
* If the frame rate limiter has been enabled by calling Clock::setFrameRateLimit(), this
|
||||
* routine will make sure that the game never exceeds the framerate specified at
|
||||
* that function call.
|
||||
*
|
||||
* If the frame rate limiter is not enabled, or has been disabled by calling
|
||||
* Clock::noFrameRateLimit(), this routine will do nothing.
|
||||
*
|
||||
* @see Clock::noFrameRateLimit(), Clock::setFrameRateLimit()
|
||||
*/
|
||||
|
||||
void Clock::limitFrameRate(void)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
// check if the frame rate limiter is on
|
||||
if (ms_frameRateLimit)
|
||||
{
|
||||
__int64 const frameRateLimitTicks = static_cast<__int64>(ms_frameFrequency / ms_frameRateLimit);
|
||||
__int64 newPoll, delta;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// get the current time
|
||||
result = QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&newPoll));
|
||||
FATAL(!result, ("Clock::limitFrameRate QPC failed"));
|
||||
|
||||
// compute elapsed time
|
||||
delta = newPoll - ms_lastPoll;
|
||||
if (delta >= frameRateLimitTicks)
|
||||
break;
|
||||
|
||||
//@todo it looks like if delta is huge we will sleep a looong time. shouldn't we check delta and the frameRatelimit before sleeping?
|
||||
if (ms_useSleep)
|
||||
{
|
||||
const DWORD sleepTicks = static_cast<DWORD>(static_cast<real>((frameRateLimitTicks - delta) / ms_frameFrequency) * 1000.0f);
|
||||
if (sleepTicks > 2)
|
||||
Sleep(sleepTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const unsigned long Clock::timeMs()
|
||||
{
|
||||
__int64 newPoll;
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&newPoll));
|
||||
double const frameTime = static_cast<double>(newPoll - ms_lastPoll) / ms_frameFrequency;
|
||||
return static_cast<unsigned long>(ms_realTimeMilliseconds + frameTime*1000.f);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const unsigned long Clock::timeSeconds()
|
||||
{
|
||||
__int64 newPoll;
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&newPoll));
|
||||
double const frameTime = static_cast<double>(newPoll - ms_lastPoll) / ms_frameFrequency;
|
||||
return static_cast<unsigned long>(ms_realTimeMilliseconds/1000.f + frameTime);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const unsigned long Clock::getFrameStartTimeMs()
|
||||
{
|
||||
return static_cast<unsigned long>(ms_realTimeMilliseconds);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
double Clock::getCurrentTime()
|
||||
{
|
||||
__int64 newPoll;
|
||||
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&newPoll));
|
||||
|
||||
double const frameTime = static_cast<double>(newPoll - ms_lastPoll) / ms_frameFrequency;
|
||||
|
||||
return getFrameStartTime() + frameTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
double Clock::getFrameStartTime()
|
||||
{
|
||||
return ms_realTimeMilliseconds * cms_secondsPerMillisecond;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const unsigned long Clock::getSecondsSinceStart()
|
||||
{
|
||||
return timeSeconds() - ms_applicationStartTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const int Clock::getTimeZone()
|
||||
{
|
||||
return ms_timeZone;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ClockNamespace::threadRoutine()
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
__int64 startCounter, endCounter;
|
||||
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&startCounter));
|
||||
ms_shutdownEvent.wait(ms_recalibrationInterval);
|
||||
QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&endCounter));
|
||||
|
||||
__int64 newFrequency = (endCounter-startCounter)*ms_recalibrationMultiplier;
|
||||
|
||||
ms_mutex.enter();
|
||||
if (ms_shutdown)
|
||||
done = true;
|
||||
else if (newFrequency)
|
||||
ms_realFrequency = static_cast<real>(newFrequency);
|
||||
ms_mutex.leave();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void Clock::setLongFramesWarningAllowed(bool allowed)
|
||||
{
|
||||
ms_longFramesWarningAllowed = allowed;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Clock.h
|
||||
//
|
||||
// Portions copyright 1998 Bootprint Entertainment
|
||||
// Portions copyright 2002 Sony Online Entertainment
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Clock_H
|
||||
#define INCLUDED_Clock_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Clock
|
||||
{
|
||||
private:
|
||||
|
||||
Clock(void);
|
||||
Clock(const Clock &);
|
||||
Clock &operator =(const Clock &);
|
||||
|
||||
private:
|
||||
|
||||
// the instantaneous frame rate of the last frame (1 / lastFrameTime)
|
||||
static real ms_lastFrameRate;
|
||||
|
||||
public:
|
||||
|
||||
static void install(bool newUseSleep, bool useRecalibrationThread);
|
||||
static void remove(void);
|
||||
|
||||
static void update(void);
|
||||
|
||||
static void debugReport();
|
||||
|
||||
static DLLEXPORT real frameTime(void);
|
||||
static real framesPerSecond(void);
|
||||
|
||||
static void noFrameRateLimit(void);
|
||||
static void setFrameRateLimit(real newFrameRateLimit);
|
||||
static void limitFrameRate(void);
|
||||
|
||||
static void setMinFrameRate(real newMinFrameRate);
|
||||
static const unsigned long timeMs();
|
||||
static const unsigned long timeSeconds();
|
||||
static const unsigned long getFrameStartTimeMs();
|
||||
static double getCurrentTime();
|
||||
static double getFrameStartTime();
|
||||
|
||||
static const unsigned long getSecondsSinceStart();
|
||||
static const int getTimeZone();
|
||||
|
||||
static void setLongFramesWarningAllowed(bool allowed);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Get the instantaneous frame rate.
|
||||
*
|
||||
* This number is really only useful for determining game performance
|
||||
*
|
||||
* @return The number of frames per second for the last frame
|
||||
* @see Clock::frameTime()
|
||||
*/
|
||||
|
||||
inline real Clock::framesPerSecond(void)
|
||||
{
|
||||
return ms_lastFrameRate;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,790 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CommandLine.h
|
||||
// Todd Fiala
|
||||
//
|
||||
// copyright 1999, Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef COMMAND_LINE_H
|
||||
#define COMMAND_LINE_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
enum OP_ListType
|
||||
{
|
||||
OPLT_Normal,
|
||||
OPLT_MinimumMatch
|
||||
};
|
||||
|
||||
#define OP_BEGIN_LIST() { CommandLine::OST_BeginList, static_cast<int>(OPLT_Normal), 0, 0, 0 }
|
||||
#define OP_END_LIST() { CommandLine::OST_EndList, 0, 0, 0, 0 }
|
||||
#define OP_BEGIN_MINIMUM_MATCH_LIST(minimumNodeCount) { CommandLine::OST_BeginList, static_cast<int>(OPLT_MinimumMatch), minimumNodeCount, 0, 0 }
|
||||
#define OP_END_MINIMUM_MATCH_LIST() { CommandLine::OST_EndList, 0, 0, 0, 0 }
|
||||
#define OP_BEGIN_SWITCH(oneIsRequired) { CommandLine::OST_BeginSwitch, oneIsRequired, 0, 0, 0 }
|
||||
#define OP_END_SWITCH() { CommandLine::OST_EndSwitch, 0, 0, 0, 0 }
|
||||
#define OP_BEGIN_LIST_NODE(multipleIsAllowed, isRequiredNode) { CommandLine::OST_BeginListNode, multipleIsAllowed, isRequiredNode, 0, 0 }
|
||||
#define OP_END_LIST_NODE() { CommandLine::OST_EndListNode, 0, 0, 0, 0 }
|
||||
#define OP_BEGIN_SWITCH_NODE(multipleIsAllowed) { CommandLine::OST_BeginSwitchNode, multipleIsAllowed, 0, 0, 0 }
|
||||
#define OP_END_SWITCH_NODE() { CommandLine::OST_EndSwitchNode, 0, 0, 0, 0 }
|
||||
#define OP_OPTION(shortName, longName, argumentPolicy) { CommandLine::OST_Option, argumentPolicy, 0, shortName, longName }
|
||||
|
||||
#define OP_SINGLE_LIST_NODE(shortName, longName, argMode, multipleIsAllowed, isRequiredNode) OP_BEGIN_LIST_NODE(multipleIsAllowed, isRequiredNode), OP_OPTION(shortName, longName, argMode), OP_END_LIST_NODE()
|
||||
#define OP_SINGLE_SWITCH_NODE(shortName, longName, argMode, multipleIsAllowed) OP_BEGIN_SWITCH_NODE(multipleIsAllowed), OP_OPTION(shortName, longName, argMode), OP_END_SWITCH_NODE()
|
||||
|
||||
//lint -save -e1923 // #define could become const
|
||||
|
||||
#define OP_ARG_NONE 0
|
||||
#define OP_ARG_REQUIRED 1
|
||||
#define OP_ARG_OPTIONAL 2
|
||||
|
||||
#define OP_NODE_REQUIRED 1
|
||||
#define OP_NODE_OPTIONAL 0
|
||||
|
||||
#define OP_MULTIPLE_ALLOWED 1
|
||||
#define OP_MULTIPLE_DENIED 0
|
||||
|
||||
#define OP_SNAME_UNTAGGED 1
|
||||
#define OP_LNAME_UNTAGGED static_cast<const char*>(0)
|
||||
|
||||
//lint -restore
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class CommandLine
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
STATIC_BUFFER_SIZE = 4096
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
enum MatchCode
|
||||
{
|
||||
MC_MATCH = 1,
|
||||
MC_NO_MATCH = 0,
|
||||
MC_REQUIRED_MATCH_MISSING = -1,
|
||||
MC_TOO_MANY_CHILDREN_MATCHES = -2,
|
||||
MC_TOO_MANY_NODE_MATCHES = -3,
|
||||
MC_ARG_NOT_EXPECTED = -4,
|
||||
MC_ARG_MISSING = -5,
|
||||
MC_UNMATCHED_OPTIONS = -6,
|
||||
MC_TOO_FEW_CHILDREN_MATCHES = -7,
|
||||
|
||||
// parse errors from client's command line
|
||||
MC_CL_OPTION_UNKNOWN = -101,
|
||||
MC_CL_PARSE_ERROR = -102,
|
||||
MC_CL_EXPECTING_ARG = -103,
|
||||
MC_CL_UNEXPECTED_ARG = -104,
|
||||
MC_CL_UNTAGGED_ARG_DENIED = -105
|
||||
};
|
||||
|
||||
enum OptionSpecType
|
||||
{
|
||||
OST_BeginList,
|
||||
OST_EndList,
|
||||
OST_BeginSwitch,
|
||||
OST_EndSwitch,
|
||||
OST_BeginListNode,
|
||||
OST_EndListNode,
|
||||
OST_BeginSwitchNode,
|
||||
OST_EndSwitchNode,
|
||||
OST_Option
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_LONG_NAME_SIZE = 64,
|
||||
MAX_ARGUMENT_SIZE = 1024
|
||||
};
|
||||
|
||||
struct OptionSpec
|
||||
{
|
||||
OptionSpecType optionType;
|
||||
int int1;
|
||||
int int2;
|
||||
char char1;
|
||||
const char *charp1;
|
||||
|
||||
#if 0
|
||||
// if this node's parent is branch head, this variable is ignored.
|
||||
// if this node's parent is list head, if node is required, at least one instance of this node must be present.
|
||||
bool nodeRequired;
|
||||
|
||||
// if this node is a list head, this variable is ignored.
|
||||
// if this node is a branch head, false = 0 or 1 child may be present, true = one child must be present.
|
||||
bool childrenRequired;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum ArgumentPolicy
|
||||
{
|
||||
AP_None,
|
||||
AP_Required,
|
||||
AP_Optional
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// -TF- clients, don't try to use this, it is here for compiler issues
|
||||
|
||||
class Option
|
||||
{
|
||||
private:
|
||||
|
||||
char shortName;
|
||||
char *longName;
|
||||
ArgumentPolicy argumentPolicy;
|
||||
|
||||
protected:
|
||||
|
||||
// disabled
|
||||
Option(void);
|
||||
Option(const Option&);
|
||||
Option &operator =(const Option&);
|
||||
|
||||
private:
|
||||
|
||||
Option(char newShortName, const char *newLongName, ArgumentPolicy newArgumentPolicy);
|
||||
|
||||
public:
|
||||
|
||||
~Option(void);
|
||||
|
||||
static bool isOptionNext(const OptionSpec *optionSpec, int optionSpecCount);
|
||||
static Option *createOption(const OptionSpec **optionSpec, int *optionSpecCount);
|
||||
|
||||
char getShortName(void) const;
|
||||
const char *getLongName(void) const;
|
||||
ArgumentPolicy getArgumentPolicy(void) const;
|
||||
|
||||
MatchCode match(void);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class Collection
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Collection(void) = 0;
|
||||
virtual MatchCode match(void) const = 0;
|
||||
|
||||
static bool isCollectionNext(const OptionSpec *optionSpec, int optionSpecCount);
|
||||
static Collection *createCollection(const OptionSpec **optionSpec, int *optionSpecCount);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
||||
class List : public Collection
|
||||
{
|
||||
friend class Collection;
|
||||
|
||||
private:
|
||||
|
||||
class Node
|
||||
{
|
||||
private:
|
||||
|
||||
Option *option;
|
||||
Collection *collection;
|
||||
bool multipleIsAllowed;
|
||||
bool isRequiredNode;
|
||||
|
||||
mutable Node *next;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
Node(void);
|
||||
Node(const Node&);
|
||||
Node &operator =(const Node&);
|
||||
|
||||
public:
|
||||
|
||||
Node(Option *newOption, Collection *newCollection, bool newMultipleIsAllowed, bool newIsRequiredNode);
|
||||
~Node(void);
|
||||
|
||||
const Option *getOption(void) const;
|
||||
const Collection *getCollection(void) const;
|
||||
bool getMultipleIsAllowed(void) const;
|
||||
bool getIsRequiredNode(void) const;
|
||||
|
||||
const Node *getNext(void) const;
|
||||
void setNext(Node *newNext) const;
|
||||
|
||||
MatchCode match(void) const;
|
||||
|
||||
static bool isNode(const OptionSpec *optionSpec, int optionCount);
|
||||
static Node *createNode(const OptionSpec **optionSpec, int *optionCount);
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Node *firstNode;
|
||||
OP_ListType listType;
|
||||
int minimumNodeCount;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
List(void);
|
||||
List(const List&);
|
||||
List &operator =(const List&);
|
||||
|
||||
private:
|
||||
|
||||
List(OP_ListType newListType, Node *newFirstNode);
|
||||
List(OP_ListType newListType, Node *newFirstNode, int newMinimumNodeCount);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~List(void);
|
||||
virtual MatchCode match(void) const;
|
||||
|
||||
static bool isListNext(const OptionSpec *optionSpec, int optionCount);
|
||||
static List *createList(const OptionSpec **optionSpec, int *optionCount);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class Switch : public Collection
|
||||
{
|
||||
friend class Collection;
|
||||
|
||||
private:
|
||||
|
||||
class Node
|
||||
{
|
||||
private:
|
||||
|
||||
Option *option;
|
||||
Collection *collection;
|
||||
bool multipleIsAllowed;
|
||||
|
||||
mutable Node *next;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
Node(void);
|
||||
Node(const Node&);
|
||||
Node &operator =(const Node&);
|
||||
|
||||
public:
|
||||
|
||||
Node(Option *newOption, Collection *newCollection, bool newMultipleIsAllowed);
|
||||
~Node(void);
|
||||
|
||||
const Option *getOption(void) const;
|
||||
const Collection *getCollection(void) const;
|
||||
bool getMultipleIsAllowed(void) const;
|
||||
|
||||
const Node *getNext(void) const;
|
||||
void setNext(Node *newNext) const;
|
||||
|
||||
MatchCode match(void) const;
|
||||
|
||||
static bool isNode(const OptionSpec *optionSpec, int optionCount);
|
||||
static Node *createNode(const OptionSpec **optionSpec, int *optionCount);
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Node *firstNode;
|
||||
bool oneNodeIsRequired;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
Switch(void);
|
||||
Switch(const Switch&);
|
||||
Switch &operator =(const Switch&);
|
||||
|
||||
private:
|
||||
|
||||
Switch(Node *newFirstNode, bool newOneNodeIsRequired);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Switch(void);
|
||||
virtual MatchCode match(void) const;
|
||||
|
||||
static bool isSwitchNext(const OptionSpec *optionSpec, int optionCount);
|
||||
static Switch *createSwitch(const OptionSpec **optionSpec, int *optionCount);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class OptionTable
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
class Record
|
||||
{
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_OCCURRENCE_COUNT = 128
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
char shortName;
|
||||
char *longName;
|
||||
int writeCount;
|
||||
int matchCount;
|
||||
char *stringArray[MAX_OCCURRENCE_COUNT];
|
||||
ArgumentPolicy argumentPolicy;
|
||||
|
||||
mutable Record *next;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
Record(void);
|
||||
Record(const Record&);
|
||||
Record &operator =(const Record&);
|
||||
|
||||
public:
|
||||
|
||||
Record(char newShortName, const char *newLongName, ArgumentPolicy newArgumentPolicy);
|
||||
~Record(void);
|
||||
|
||||
char getShortName(void) const;
|
||||
const char *getLongName(void) const;
|
||||
|
||||
void addOccurrence(const char *newString);
|
||||
void addMatch(void);
|
||||
|
||||
const char *getString(int occurrenceIndex) const;
|
||||
int getWriteCount(void) const;
|
||||
int getMatchCount(void) const;
|
||||
|
||||
const Record *getNext(void) const;
|
||||
Record *getNext(void);
|
||||
void setNext(Record *newNext) const;
|
||||
|
||||
ArgumentPolicy getArgumentPolicy(void) const;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Record *firstRecord;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
OptionTable(const OptionTable&);
|
||||
OptionTable &operator =(const OptionTable&);
|
||||
|
||||
public:
|
||||
|
||||
OptionTable(void);
|
||||
~OptionTable(void);
|
||||
|
||||
Record *createOptionRecord(char shortName, const char *longName, ArgumentPolicy newArgumentPolicy);
|
||||
|
||||
Record *findOptionRecord(char shortName) const;
|
||||
Record *findOptionRecord(const char *longName) const;
|
||||
|
||||
bool getAllOptionsMatched(void) const;
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
|
||||
enum TokenType
|
||||
{
|
||||
TT_Error,
|
||||
TT_End,
|
||||
TT_DoubleDash,
|
||||
TT_ShortOption,
|
||||
TT_LongOption,
|
||||
TT_Equal,
|
||||
TT_Argument
|
||||
};
|
||||
|
||||
class Token
|
||||
{
|
||||
friend class Lexer;
|
||||
|
||||
private:
|
||||
|
||||
TokenType tokenType;
|
||||
char name[MAX_LONG_NAME_SIZE];
|
||||
char argument[MAX_ARGUMENT_SIZE];
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
Token(const Token&);
|
||||
Token &operator =(const Token&);
|
||||
|
||||
public:
|
||||
|
||||
Token(void);
|
||||
|
||||
TokenType getTokenType(void) const;
|
||||
char getShortName(void) const;
|
||||
const char *getLongName(void);
|
||||
const char *getArgument(void);
|
||||
|
||||
};
|
||||
|
||||
// -TF- so Token can see the TokenType enums --- this is making me puke...
|
||||
friend class Token;
|
||||
|
||||
private:
|
||||
|
||||
const char *nextCharacter;
|
||||
|
||||
private:
|
||||
|
||||
// disabled
|
||||
Lexer(void);
|
||||
Lexer(const Lexer&);
|
||||
Lexer &operator =(const Lexer&);
|
||||
|
||||
private:
|
||||
|
||||
void gobbleWhitespace(void);
|
||||
bool gobbleString(bool isRequired, char *stringBuffer, int bufferSize);
|
||||
|
||||
public:
|
||||
|
||||
explicit Lexer(const char *newBuffer);
|
||||
~Lexer(void);
|
||||
|
||||
bool getNextToken(Token *token);
|
||||
const char *getNextCharacter(void);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// needed so that option can access variable optionTable
|
||||
friend class Option;
|
||||
|
||||
private:
|
||||
|
||||
static bool installed;
|
||||
static bool wasParsed;
|
||||
static char buffer[STATIC_BUFFER_SIZE];
|
||||
static int bufferSize;
|
||||
static Collection *treeRoot;
|
||||
static OptionTable *optionTable;
|
||||
static int absorbedStringCount;
|
||||
|
||||
private:
|
||||
|
||||
static bool findNextOccurence(char shortName, int *occurrenceIndex);
|
||||
static bool findNextOccurence(const char *longName, int *occurrenceIndex);
|
||||
|
||||
static bool getOptionArgExists(char shortName, int occurrenceIndex);
|
||||
static bool getOptionArgExists(const char *longName, int occurrenceIndex);
|
||||
|
||||
static void buildOptionTree(const OptionSpec *specList, int specCount);
|
||||
static MatchCode parseCommandLineBuffer(void);
|
||||
|
||||
public:
|
||||
|
||||
static void install(void);
|
||||
static void remove(void);
|
||||
|
||||
static void absorbString(const char *newString);
|
||||
static void absorbStrings(const char **stringArray, int stringCount);
|
||||
|
||||
static const char *getPostCommandLineString(void);
|
||||
|
||||
static MatchCode parseOptions(const OptionSpec *optionTree, int optionSpecCount);
|
||||
|
||||
static bool getOptionExists(char shortName, int occurrenceIndex = 0);
|
||||
static bool getOptionExists(const char *longName, int occurrenceIndex = 0);
|
||||
|
||||
static int getOccurrenceCount(char shortName);
|
||||
static int getOccurrenceCount(const char *longName);
|
||||
|
||||
static const char *getOptionString(char shortName, int occurrenceIndex = 0);
|
||||
static const char *getOptionString(const char *longName, int occurrenceIndex = 0);
|
||||
|
||||
static int getOptionInt(char shortName, int occurrenceIndex = 0);
|
||||
static int getOptionInt(const char *longName, int occurrenceIndex = 0);
|
||||
|
||||
static int getUntaggedOccurrenceCount(void);
|
||||
static const char *getUntaggedString(int occurrenceIndex = 0);
|
||||
static int getUntaggedInt(int occurrenceIndex = 0);
|
||||
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline char CommandLine::Option::getShortName(void) const
|
||||
{
|
||||
return shortName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const char *CommandLine::Option::getLongName(void) const
|
||||
{
|
||||
return longName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline CommandLine::ArgumentPolicy CommandLine::Option::getArgumentPolicy(void) const
|
||||
{
|
||||
return argumentPolicy;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline const CommandLine::Option *CommandLine::List::Node::getOption(void) const
|
||||
{
|
||||
return option;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const CommandLine::Collection *CommandLine::List::Node::getCollection(void) const
|
||||
{
|
||||
return collection;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool CommandLine::List::Node::getMultipleIsAllowed(void) const
|
||||
{
|
||||
return multipleIsAllowed;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool CommandLine::List::Node::getIsRequiredNode(void) const
|
||||
{
|
||||
return isRequiredNode;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const CommandLine::List::Node *CommandLine::List::Node::getNext(void) const
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void CommandLine::List::Node::setNext(Node *newNext) const
|
||||
{
|
||||
next = newNext;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline const CommandLine::Option *CommandLine::Switch::Node::getOption(void) const
|
||||
{
|
||||
return option;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const CommandLine::Collection *CommandLine::Switch::Node::getCollection(void) const
|
||||
{
|
||||
return collection;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline bool CommandLine::Switch::Node::getMultipleIsAllowed(void) const
|
||||
{
|
||||
return multipleIsAllowed;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const CommandLine::Switch::Node *CommandLine::Switch::Node::getNext(void) const
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void CommandLine::Switch::Node::setNext(
|
||||
Node *newNext
|
||||
) const
|
||||
{
|
||||
next = newNext;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline char CommandLine::OptionTable::Record::getShortName(void) const
|
||||
{
|
||||
return shortName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const char *CommandLine::OptionTable::Record::getLongName(void) const
|
||||
{
|
||||
return longName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void CommandLine::OptionTable::Record::addMatch(void)
|
||||
{
|
||||
DEBUG_FATAL(matchCount >= writeCount, ("match overflow"));
|
||||
++matchCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const char *CommandLine::OptionTable::Record::getString(
|
||||
int occurrenceIndex
|
||||
) const
|
||||
{
|
||||
DEBUG_FATAL(occurrenceIndex >= writeCount, ("index out of range: val/max %d/%d", occurrenceIndex, writeCount-1));
|
||||
return stringArray[occurrenceIndex];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int CommandLine::OptionTable::Record::getWriteCount(void) const
|
||||
{
|
||||
return writeCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int CommandLine::OptionTable::Record::getMatchCount(void) const
|
||||
{
|
||||
return matchCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const CommandLine::OptionTable::Record *CommandLine::OptionTable::Record::getNext(void) const
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline CommandLine::OptionTable::Record *CommandLine::OptionTable::Record::getNext(void)
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void CommandLine::OptionTable::Record::setNext(
|
||||
Record *newNext
|
||||
) const
|
||||
{
|
||||
next = newNext;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline CommandLine::ArgumentPolicy CommandLine::OptionTable::Record::getArgumentPolicy(void) const
|
||||
{
|
||||
return argumentPolicy;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline CommandLine::Lexer::TokenType CommandLine::Lexer::Token::getTokenType(void) const
|
||||
{
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline char CommandLine::Lexer::Token::getShortName(void) const
|
||||
{
|
||||
DEBUG_FATAL(tokenType != TT_ShortOption, ("attempted to get short name for token type %d", tokenType));
|
||||
return name[0];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const char *CommandLine::Lexer::Token::getLongName(void)
|
||||
{
|
||||
DEBUG_FATAL(tokenType != TT_LongOption, ("attempted to get long name for token type %d", tokenType));
|
||||
return name;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const char *CommandLine::Lexer::Token::getArgument(void)
|
||||
{
|
||||
DEBUG_FATAL(tokenType != TT_Argument, ("attempted to get argument for token type %d", tokenType));
|
||||
return argument;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline const char *CommandLine::Lexer::getNextCharacter(void)
|
||||
{
|
||||
return nextCharacter;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline void CommandLine::Lexer::gobbleWhitespace(void)
|
||||
{
|
||||
DEBUG_FATAL(!nextCharacter, ("null nextCharacter"));
|
||||
while (isspace(*nextCharacter))
|
||||
++nextCharacter;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int CommandLine::getUntaggedOccurrenceCount(void)
|
||||
{
|
||||
return getOccurrenceCount(OP_SNAME_UNTAGGED);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const char *CommandLine::getUntaggedString(
|
||||
int occurrenceIndex
|
||||
)
|
||||
{
|
||||
return getOptionString(OP_SNAME_UNTAGGED, occurrenceIndex);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int CommandLine::getUntaggedInt(
|
||||
int occurrenceIndex
|
||||
)
|
||||
{
|
||||
return getOptionInt(OP_SNAME_UNTAGGED, occurrenceIndex);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConfigFile.h
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef CONFIG_FILE_H
|
||||
#define CONFIG_FILE_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class StringCompare;
|
||||
|
||||
#include "sharedFoundation/Tag.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/// Provide access to configuration file paramaters.
|
||||
class ConfigFile
|
||||
{
|
||||
public:
|
||||
|
||||
/** Represents a single value of a key/value pair
|
||||
*
|
||||
* Stored as a string, but can be cast and returned as an int, bool, and float as well
|
||||
*/
|
||||
class Element
|
||||
{
|
||||
public:
|
||||
Element();
|
||||
explicit Element(const char *entry);
|
||||
virtual ~Element(void);
|
||||
Element(const Element&);
|
||||
Element &operator =(const Element&);
|
||||
int getAsInt(void) const;
|
||||
bool getAsBool(void) const;
|
||||
float getAsFloat(void) const;
|
||||
const char *getAsString(void) const;
|
||||
Tag getAsTag(void) const;
|
||||
|
||||
private:
|
||||
/// a buffer holding the entry string, which may be recast to other types
|
||||
char *m_entry;
|
||||
};
|
||||
typedef stdlist<Element *>::fwd ElementList;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
///Represents a single key, which may hold multiple ordered Elements as values
|
||||
class Key
|
||||
{
|
||||
public:
|
||||
Key (const char *name, const char *value, bool lazyAdd = false);
|
||||
virtual ~Key(void);
|
||||
const char *getName(void) const;
|
||||
bool getLazyAdd(void) const;
|
||||
int getAsInt(int index, int defaultValue) const;
|
||||
bool getAsBool(int index, bool defaultValue) const;
|
||||
float getAsFloat(int index, float defaultValue) const;
|
||||
const char *getAsString(int index, const char *defaultValue) const;
|
||||
Tag getAsTag(int index, Tag defaultValue) const;
|
||||
int getCount(void) const;
|
||||
void addValue(const char *value);
|
||||
void dump(const char *keyName) const;
|
||||
|
||||
private:
|
||||
/// disabled
|
||||
Key(void);
|
||||
/// disabled
|
||||
Key(const Key&);
|
||||
/// disabled
|
||||
Key &operator =(const Key&);
|
||||
|
||||
private:
|
||||
///A list of element values, since are elements are unique and order is important
|
||||
ElementList *m_elements;
|
||||
///String representation of the key's name
|
||||
char* m_name;
|
||||
/// track whether this was added lazily (not explicitly in the config file)
|
||||
bool m_lazyAdd;
|
||||
};
|
||||
typedef stdmap<const char *, Key *, StringCompare>::fwd KeyMap;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/** A scoping mechanism for keys
|
||||
*
|
||||
* All keys exist inside a section, i.e. [Section]
|
||||
* a = 5
|
||||
*/
|
||||
class Section
|
||||
{
|
||||
public:
|
||||
explicit Section (const char *name);
|
||||
~Section(void);
|
||||
const char *getName(void) const;
|
||||
Key *findKey(const char *key) const;
|
||||
int getKeyInt (const char *key, int index, int defaultValue = 0) const;
|
||||
bool getKeyBool (const char *key, int index, bool defaultValue = false) const;
|
||||
float getKeyFloat (const char *key, int index, float defaultValue = 0.f) const;
|
||||
const char *getKeyString(const char *key, int index, const char *defaultValue = NULL) const;
|
||||
Tag getKeyTag (const char *key, int index, Tag defaultValue = 0) const;
|
||||
int getKeyCount(const char *key) const;
|
||||
void addKey(const char *keyName, const char *value, bool lazyAdd = false);
|
||||
void removeKey(const char *key);
|
||||
void dump(void) const;
|
||||
bool getKeyExists(const char *key) const;
|
||||
|
||||
private:
|
||||
/// disabled
|
||||
Section(void);
|
||||
/// disabled
|
||||
Section(const Section&);
|
||||
/// disabled
|
||||
Section &operator =(const Section&);
|
||||
|
||||
private:
|
||||
/** A map of the keys
|
||||
*
|
||||
* Use a map for speed, and since keys are unique
|
||||
*/
|
||||
KeyMap *m_keys;
|
||||
///String representation of the section's name
|
||||
char* m_name;
|
||||
};
|
||||
typedef stdmap<const char *, Section *, StringCompare>::fwd SectionMap;
|
||||
|
||||
public:
|
||||
//public interface
|
||||
static void install(void);
|
||||
static bool isInstalled(void);
|
||||
static bool isEmpty();
|
||||
static Section *getSection(const char *name);
|
||||
static bool loadFile(char const * fileName);
|
||||
static bool loadFromBuffer(char const * buffer, int length);
|
||||
static bool loadFromCommandLine(const char *buffer);
|
||||
static Section *createSection(const char *name);
|
||||
static void removeSection(const char *name);
|
||||
static void dump(void);
|
||||
//accessors using indexes
|
||||
static int getKeyInt (const char *section, const char *key, int index, int defaultValue);
|
||||
static bool getKeyBool (const char *section, const char *key, int index, bool defaultValue);
|
||||
static float getKeyFloat (const char *section, const char *key, int index, float defaultValue);
|
||||
static const char *getKeyString(const char *section, const char *key, int index, const char *defaultValue);
|
||||
static Tag getKeyTag (const char *section, const char *key, int index, Tag defaultValue);
|
||||
//accessors defaulting to retrieving the last entered value
|
||||
static DLLEXPORT int getKeyInt (const char *section, const char *key, int defaultValue, bool overrideLazyAdds = false);
|
||||
static DLLEXPORT bool getKeyBool (const char *section, const char *key, bool defaultValue, bool overrideLazyAdds = false);
|
||||
static float getKeyFloat (const char *section, const char *key, float defaultValue, bool overrideLazyAdds = false);
|
||||
static const char *getKeyString(const char *section, const char *key, const char *defaultValue, bool overrideLazyAdds = false);
|
||||
static Tag getKeyTag (const char *section, const char *key, Tag defaultValue, bool overrideLazyAdds = false);
|
||||
|
||||
private:
|
||||
/// disabled
|
||||
ConfigFile(void);
|
||||
/// disabled
|
||||
ConfigFile(const ConfigFile &);
|
||||
/// disabled
|
||||
ConfigFile &operator =(const ConfigFile &);
|
||||
|
||||
private:
|
||||
//private functions
|
||||
static void processLine(const char *line);
|
||||
static void processKeys(const char *key);
|
||||
static void remove(void);
|
||||
|
||||
private:
|
||||
//private data members
|
||||
static SectionMap *ms_sections;
|
||||
static Section *ms_currentSection;
|
||||
static const char *ms_IncludeDelimiter;
|
||||
static bool ms_installed;
|
||||
static bool ms_logConfigSettings;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConstCharCrcLowerString.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/ConstCharCrcLowerString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
ConstCharCrcLowerString::ConstCharCrcLowerString(const char *string)
|
||||
: CrcLowerString(string, PersistentCrcString::CC_true)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcLowerString::~ConstCharCrcLowerString()
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,27 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConstCharCrcLowerString.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConstCharCrcLowerString_H
|
||||
#define INCLUDED_ConstCharCrcLowerString_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/CrcLowerString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ConstCharCrcLowerString : public CrcLowerString
|
||||
{
|
||||
public:
|
||||
ConstCharCrcLowerString(const char *string);
|
||||
virtual ~ConstCharCrcLowerString();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConstCharCrcString.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/ConstCharCrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
ConstCharCrcString::ConstCharCrcString(const char *string)
|
||||
: CrcString(),
|
||||
m_buffer(string)
|
||||
{
|
||||
calculateCrc ();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcString::ConstCharCrcString(const char *string, uint32 crc)
|
||||
: CrcString(),
|
||||
m_buffer(string)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
calculateCrc();
|
||||
DEBUG_FATAL(m_crc != crc, ("calculated and specified crc values do not match"));
|
||||
#endif
|
||||
m_crc = crc;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcString::ConstCharCrcString(ConstCharCrcString const &rhs)
|
||||
: CrcString(rhs.m_crc),
|
||||
m_buffer(rhs.m_buffer)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcString::~ConstCharCrcString()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
char const * ConstCharCrcString::getString() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ConstCharCrcString::clear()
|
||||
{
|
||||
DEBUG_FATAL(true, ("cannot clear a ConstCharCrcString"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ConstCharCrcString::set(char const *, bool)
|
||||
{
|
||||
DEBUG_FATAL(true, ("cannot clear a ConstCharCrcString"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ConstCharCrcString::set(char const *, uint32)
|
||||
{
|
||||
DEBUG_FATAL(true, ("cannot clear a ConstCharCrcString"));
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,45 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConstCharCrcString.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConstCharCrcString_H
|
||||
#define INCLUDED_ConstCharCrcString_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/CrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ConstCharCrcString : public CrcString
|
||||
{
|
||||
public:
|
||||
|
||||
ConstCharCrcString(const char *string);
|
||||
ConstCharCrcString(const char *string, uint32 crc);
|
||||
ConstCharCrcString(ConstCharCrcString const &);
|
||||
virtual ~ConstCharCrcString();
|
||||
|
||||
virtual char const * getString() const;
|
||||
|
||||
virtual void clear();
|
||||
virtual void set(char const * string, bool applyNormalize);
|
||||
virtual void set(char const * string, uint32 crc);
|
||||
|
||||
private:
|
||||
|
||||
ConstCharCrcString();
|
||||
ConstCharCrcString & operator =(ConstCharCrcString const &);
|
||||
|
||||
private:
|
||||
|
||||
char const * const m_buffer;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrashReportInformation.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/CrashReportInformation.h"
|
||||
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace CrashReportInformationNamespace
|
||||
{
|
||||
typedef std::vector<char *> TextVector;
|
||||
typedef std::vector<char const *> ConstTextVector;
|
||||
TextVector ms_staticText;
|
||||
ConstTextVector ms_dynamicText;
|
||||
}
|
||||
using namespace CrashReportInformationNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void CrashReportInformation::install()
|
||||
{
|
||||
ExitChain::add(&remove, "CrashReportInformation::remove");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrashReportInformation::remove()
|
||||
{
|
||||
while (!ms_staticText.empty())
|
||||
{
|
||||
delete [] ms_staticText.back();
|
||||
ms_staticText.pop_back();
|
||||
}
|
||||
|
||||
ms_dynamicText.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrashReportInformation::addStaticText(char const * format, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
|
||||
char buffer[256];
|
||||
vsnprintf(buffer, sizeof(buffer), format, va);
|
||||
ms_staticText.push_back(DuplicateString(buffer));
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrashReportInformation::addDynamicText(char const * text)
|
||||
{
|
||||
ms_dynamicText.push_back(text);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrashReportInformation::removeDynamicText(char const * text)
|
||||
{
|
||||
ConstTextVector::iterator i = std::find(ms_dynamicText.begin(), ms_dynamicText.end(), text);
|
||||
if (i != ms_dynamicText.end())
|
||||
ms_dynamicText.erase(i);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
char const * CrashReportInformation::getEntry(int index)
|
||||
{
|
||||
if (index < static_cast<int>(ms_staticText.size()))
|
||||
return ms_staticText[index];
|
||||
|
||||
index -= static_cast<int>(ms_staticText.size());
|
||||
if (index < static_cast<int>(ms_dynamicText.size()))
|
||||
return ms_dynamicText[index];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,36 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrashReportInformation.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CrashReportInformation_H
|
||||
#define INCLUDED_CrashReportInformation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class CrashReportInformation
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
static DLLEXPORT void addStaticText(char const * format, ...);
|
||||
|
||||
static void addDynamicText(char const * text);
|
||||
static void removeDynamicText(char const * text);
|
||||
|
||||
static char const * getEntry(int index);
|
||||
|
||||
private:
|
||||
CrashReportInformation();
|
||||
CrashReportInformation(CrashReportInformation const &);
|
||||
CrashReportInformation & operator=(CrashReportInformation const &);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Crc.cpp
|
||||
//
|
||||
// adapted from Ross Williams' public domain crc code.
|
||||
//
|
||||
// Portions copyright 1998 Bootprint Entertainment
|
||||
// Portions copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
|
||||
#include "sharedFoundation/TemporaryCrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const uint32 Crc::crcNull = Crc::calculate ("");
|
||||
|
||||
// ======================================================================
|
||||
|
||||
static const uint32 crctable[256] =
|
||||
{
|
||||
0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
|
||||
0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
|
||||
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75,
|
||||
0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD,
|
||||
0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5,
|
||||
0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D,
|
||||
0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
|
||||
0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D,
|
||||
0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072,
|
||||
0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA,
|
||||
0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02,
|
||||
0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
|
||||
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692,
|
||||
0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A,
|
||||
0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2,
|
||||
0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A,
|
||||
0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
|
||||
0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53,
|
||||
0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B,
|
||||
0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623,
|
||||
0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B,
|
||||
0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
|
||||
0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B,
|
||||
0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3,
|
||||
0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C,
|
||||
0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24,
|
||||
0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
|
||||
0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654,
|
||||
0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C,
|
||||
0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4,
|
||||
0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C,
|
||||
0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
|
||||
};
|
||||
|
||||
const uint32 CRC_INIT = 0xFFFFFFFF;
|
||||
|
||||
const uint32 Crc::crcInit = CRC_INIT;
|
||||
|
||||
|
||||
// ======================================================================
|
||||
|
||||
uint32 Crc::calculate(const char *string)
|
||||
{
|
||||
uint32 crc;
|
||||
|
||||
if (!string)
|
||||
return 0;
|
||||
|
||||
for (crc = CRC_INIT; *string; ++string)
|
||||
crc = crctable[((crc>>24) ^ static_cast<byte>(*string)) & 0xFF] ^ (crc << 8);
|
||||
|
||||
return (crc ^ CRC_INIT);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
|
||||
uint32 Crc::calculateWithToLower(const char *string)
|
||||
{
|
||||
uint32 crc;
|
||||
|
||||
if (!string)
|
||||
return 0;
|
||||
|
||||
for (crc = CRC_INIT; *string; ++string)
|
||||
crc = crctable[((crc>>24) ^ static_cast<uint32>(tolower(*string))) & 0xFF] ^ (crc << 8);
|
||||
|
||||
return (crc ^ CRC_INIT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint32 Crc::calculate(const void *data, int length, uint32 initCrc)
|
||||
{
|
||||
DEBUG_FATAL(!data, ("null data arg"));
|
||||
|
||||
uint32 crc;
|
||||
const byte *d = reinterpret_cast<const byte *>(data);
|
||||
|
||||
for (crc = initCrc; length; --length, ++d)
|
||||
crc = crctable[((crc>>24) ^ static_cast<uint32>(*d)) & 0xFF] ^ (crc << 8);
|
||||
|
||||
return (crc ^ initCrc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint32 Crc::normalizeAndCalculate(const char *string)
|
||||
{
|
||||
return TemporaryCrcString(string, true).getCrc();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,35 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Crc.h
|
||||
// ala diaz
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Crc_H
|
||||
#define INCLUDED_Crc_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// Functions that return the CRC value of either strings or blocks of data.
|
||||
|
||||
class Crc
|
||||
{
|
||||
public:
|
||||
|
||||
// CRC of the empty string ("")
|
||||
static const uint32 crcNull;
|
||||
static const uint32 crcInit;
|
||||
|
||||
public:
|
||||
|
||||
static uint32 calculate(const char *string);
|
||||
static uint32 calculate(const void *data, int len, uint32 initCrc = crcInit);
|
||||
static uint32 normalizeAndCalculate(const char *string);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,224 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrcLowerString.cpp
|
||||
// Portions copyright 1998 Bootprint Entertainment
|
||||
// Portions copyright 2002 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/CrcLowerString.h"
|
||||
|
||||
#include "sharedFoundation/TemporaryCrcString.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/MemoryBlockManager.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const CrcLowerString CrcLowerString::empty("", PersistentCrcString::CC_true);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITH_INSTALL(CrcLowerString, true, 0, 0, 0);
|
||||
|
||||
// ======================================================================
|
||||
// Compute the CRC for a string
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// The CRC for the specified string
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// This routine is provided so that other code can calculate the CRC for
|
||||
// a CrcLowerString without having to create a CrcLowerString, enabling the user
|
||||
// to call the compare(const char *, uint32) function.
|
||||
//
|
||||
// This routine currently simply calls CRC32::calculateWithToLower() on the specified
|
||||
// string.
|
||||
|
||||
uint32 CrcLowerString::calculateCrc(const char *newString)
|
||||
{
|
||||
return TemporaryCrcString(newString, true).getCrc();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Construct a new CrcLowerString, initialized with empty string.
|
||||
*
|
||||
* This function is provided to satisfy the requirements for a
|
||||
* std::set<CrcLowerString> and related STL containers.
|
||||
*/
|
||||
|
||||
CrcLowerString::CrcLowerString()
|
||||
: PersistentCrcString()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Construct a new CrcLowerString
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// The constructor will copy its argument into local memory, and then
|
||||
// call CrcLowerString::calculateCrc() on the string to compute the CRC once.
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// CrcLowerString::calculateCrc()
|
||||
|
||||
CrcLowerString::CrcLowerString(const char *newString)
|
||||
: PersistentCrcString(newString, true)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Construct a new CrcLowerString.
|
||||
*
|
||||
* The constructor will copy its argument into local memory. It will
|
||||
* assume that the specified CRC is correct for the string.
|
||||
*
|
||||
* @param newString String to generate the CRC String from
|
||||
* @param newCrc CRC for the string
|
||||
*/
|
||||
|
||||
CrcLowerString::CrcLowerString(const char *newString, uint32 newCrc)
|
||||
: PersistentCrcString(newString, newCrc)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Copy construct a new CrcLowerString from an existing CrcLowerString.
|
||||
*
|
||||
* The constructor will copy its argument into local memory.
|
||||
*
|
||||
* This function normally would not be present since there shouldn't
|
||||
* be much need to duplicate a crc-based string. However, the need
|
||||
* arose to use a CrcLowerString as a key for a std::map, so the
|
||||
* copy constructor was needed.
|
||||
*
|
||||
* @param rhs Existing CrcLowerString to copy
|
||||
*/
|
||||
|
||||
CrcLowerString::CrcLowerString(const CrcLowerString &rhs)
|
||||
: PersistentCrcString(rhs)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
CrcLowerString::CrcLowerString(const char *newString, PersistentCrcString::ConstChar)
|
||||
: PersistentCrcString(newString, PersistentCrcString::CC_true)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Destroy a CrcLowerString.
|
||||
*
|
||||
* This routine will free the resources associated with this CrcLowerString.
|
||||
*/
|
||||
|
||||
CrcLowerString::~CrcLowerString(void)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set the new string for a CrcLowerString.
|
||||
*
|
||||
* This routine will delete the old string and reallocate the new string.
|
||||
* It will also recompute the CRC for the string.
|
||||
*
|
||||
* @param newString The new value of the CrcLowerString
|
||||
*/
|
||||
|
||||
void CrcLowerString::setString(const char *newString)
|
||||
{
|
||||
set(newString, true);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Compare this CrcLowerString with a string and a CRC.
|
||||
*
|
||||
* The return value does not indicate the lexiographic ordering of the
|
||||
* strings, because they are first compared using the CRC, and only if
|
||||
* the CRC's match are they compared by strcmp().
|
||||
*
|
||||
* @param otherString String to compare against
|
||||
* @param otherCrc CRC of the string to compare against
|
||||
* @return See Remarks section
|
||||
*/
|
||||
|
||||
int CrcLowerString::compare(const char *otherString, uint32 otherCrc) const
|
||||
{
|
||||
NOT_NULL(otherString);
|
||||
|
||||
const uint32 crc = getCrc();
|
||||
|
||||
if (crc < otherCrc)
|
||||
return -1;
|
||||
|
||||
if (crc > otherCrc)
|
||||
return 1;
|
||||
|
||||
char const *string = getString();
|
||||
for (int i = 0; ; ++i)
|
||||
{
|
||||
const int a = string[i];
|
||||
const int b = tolower(otherString[i]);
|
||||
|
||||
if (!a || !b || a != b)
|
||||
{
|
||||
if (a < b)
|
||||
return -1;
|
||||
|
||||
if (a > b)
|
||||
return 1;
|
||||
|
||||
if (a == b)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Compare this CrcLowerString with another.
|
||||
*
|
||||
* The return value does not indicate the lexiographic ordering of the
|
||||
* strings, because they are first compared using the CRC, and only if
|
||||
* the CRC's match are they compared by strcmp().
|
||||
*
|
||||
* @param otherString CrcLowerString to compare against
|
||||
* @return See Remarks section
|
||||
*/
|
||||
|
||||
int CrcLowerString::compare(const CrcLowerString &otherString) const
|
||||
{
|
||||
return compare(otherString.getString(), otherString.getCrc());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
*
|
||||
* Perform an assignment of the CrcLowerString object.
|
||||
*
|
||||
* NOTE: use of this function during game runtime likely is an indication
|
||||
* of a flawed design. This function was added to support tools where
|
||||
* simplicity overrode efficiency concerns.
|
||||
*
|
||||
* @param rhs the source CrcLowerString object to copy into the left-hand-side object
|
||||
*/
|
||||
|
||||
CrcLowerString &CrcLowerString::operator =(const CrcLowerString &rhs)
|
||||
{
|
||||
set(rhs.getString(), rhs.getCrc());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,120 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrcLowerString.h
|
||||
// Portions copyright 1998 Bootprint Entertainment
|
||||
// Portions copyright 2002 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CrcLowerString_H
|
||||
#define INCLUDED_CrcLowerString_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/MemoryBlockManagerMacros.h"
|
||||
#include "sharedFoundation/PersistentCrcString.h"
|
||||
|
||||
class MemoryBlockManager;
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* The CrcLowerString class is designed to permit faster case-insensitive
|
||||
* string searching. The strings are first compared using CRC, and then
|
||||
* compared using a lowercasing strcmp() call only if the CRC's match.
|
||||
*
|
||||
* Note that sorting strings by the return value of compare() will not
|
||||
* sorted lexiographic manner, because the strings are first compared by
|
||||
* their CRC which does not indicate lexiographic ordering of the strings.
|
||||
* Even so, CRC strings may still be stored and searched upon by various
|
||||
* high-performance search algorithms like a binary searches.
|
||||
*/
|
||||
|
||||
class CrcLowerString : public PersistentCrcString
|
||||
{
|
||||
MEMORY_BLOCK_MANAGER_INTERFACE_WITH_INSTALL;
|
||||
|
||||
public:
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
struct LessPtrComparator
|
||||
{
|
||||
//-- returns true if a is less than b
|
||||
bool operator ()(const CrcLowerString * a, const CrcLowerString * b) const;
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
/**
|
||||
* Provide a predicate that compares CrcLowerString instances based on
|
||||
* the underlying string lexicographical comparison (case sensitive).
|
||||
*
|
||||
* The standard CrcLowerString operator < compares efficiently based
|
||||
* on the Crc value. Typically this is what you want, for presumably
|
||||
* the user is using CrcLowerString instances to speed up comparisons.
|
||||
* However, in the case where you want to sort CrcLowerString instances
|
||||
* based on the lexicographical (ABC) ordering, use this function object.
|
||||
* Sorts identically to strcmp().
|
||||
*
|
||||
* Can be used as a predicate object (functor) in STL routines.
|
||||
*/
|
||||
|
||||
struct LessAbcOrderReferenceComparator
|
||||
{
|
||||
bool operator ()(const CrcLowerString &a, const CrcLowerString &b) const;
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
public:
|
||||
|
||||
static uint32 calculateCrc(const char *newString);
|
||||
|
||||
public:
|
||||
|
||||
CrcLowerString();
|
||||
explicit CrcLowerString(const char *newString);
|
||||
CrcLowerString(const char *newString, uint32 newCrc);
|
||||
CrcLowerString(const CrcLowerString &rhs);
|
||||
virtual ~CrcLowerString(void);
|
||||
|
||||
void setString(const char *newString);
|
||||
|
||||
int compare(const char *otherString, uint32 otherCrc) const;
|
||||
int compare(const CrcLowerString &otherString) const;
|
||||
|
||||
CrcLowerString &operator =(const CrcLowerString &rhs);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* A CrcLowerString representation of the empty string (i.e. "").
|
||||
*/
|
||||
static const CrcLowerString empty;
|
||||
|
||||
protected:
|
||||
|
||||
CrcLowerString(const char *newString, PersistentCrcString::ConstChar);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
// class CrcLowerString::LessPtrComparator
|
||||
// ======================================================================
|
||||
|
||||
inline bool CrcLowerString::LessPtrComparator::operator () (const CrcLowerString * a, const CrcLowerString * b) const
|
||||
{
|
||||
return *a < *b;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// class CrcLowerString::LessAbcOrderReferenceComparator
|
||||
// ======================================================================
|
||||
|
||||
inline bool CrcLowerString::LessAbcOrderReferenceComparator::operator ()(const CrcLowerString &a, const CrcLowerString &b) const
|
||||
{
|
||||
return (strcmp(a.getString(), b.getString()) < 0);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrcString.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/CrcString.h"
|
||||
|
||||
#include "sharedFoundation/Crc.h"
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Normalize a string.
|
||||
*
|
||||
* This function will clean up a string. All alpha characters will be
|
||||
* changed to lower case, all backslashes will be converted to forward
|
||||
* slashes, all dots following a slash will be removed, and consecutive
|
||||
* slashes will be converted into a single slash.
|
||||
*/
|
||||
|
||||
void CrcString::normalize(char *output, const char *input)
|
||||
{
|
||||
bool previousIsSlash = true;
|
||||
for ( ; *input; ++input)
|
||||
{
|
||||
const char c = *input;
|
||||
if (c == '\\' || c == '/')
|
||||
{
|
||||
if (!previousIsSlash)
|
||||
{
|
||||
// convert all backslashes to forward slashes and disallow multiple slashes in a row
|
||||
*(output++) = '/';
|
||||
previousIsSlash = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (c == '.')
|
||||
{
|
||||
// disallow dots after slashes. this will also handle multiple dots, and slashes following the dots
|
||||
if (!previousIsSlash)
|
||||
*(output++) = '.';
|
||||
}
|
||||
else
|
||||
{
|
||||
// lowercase all other characters
|
||||
*(output++) = static_cast<char>(tolower(c));
|
||||
previousIsSlash = false;
|
||||
}
|
||||
}
|
||||
|
||||
*output = '\0';
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
CrcString::CrcString()
|
||||
: m_crc(Crc::crcNull)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
CrcString::CrcString(uint32 crc)
|
||||
: m_crc(crc)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
CrcString::~CrcString()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrcString::calculateCrc()
|
||||
{
|
||||
m_crc = Crc::calculate(getString());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::isEmpty() const
|
||||
{
|
||||
const char * const str = getString ();
|
||||
return !str || str[0] == '\0';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrcString::set(CrcString const & rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
return;
|
||||
|
||||
if (rhs.isEmpty())
|
||||
clear();
|
||||
else
|
||||
set(rhs.getString(), rhs.getCrc());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::operator ==(CrcString const & rhs) const
|
||||
{
|
||||
return !(*this != rhs);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::operator !=(CrcString const & rhs) const
|
||||
{
|
||||
return m_crc != rhs.m_crc || strcmp(getString(), rhs.getString()) != 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::operator < (CrcString const & rhs) const
|
||||
{
|
||||
if (m_crc < rhs.m_crc)
|
||||
return true;
|
||||
if (m_crc > rhs.m_crc)
|
||||
return false;
|
||||
|
||||
return strcmp(getString(), rhs.getString()) < 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::operator <=(CrcString const & rhs) const
|
||||
{
|
||||
return !(*this > rhs);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::operator > (CrcString const & rhs) const
|
||||
{
|
||||
if (m_crc > rhs.m_crc)
|
||||
return true;
|
||||
if (m_crc < rhs.m_crc)
|
||||
return false;
|
||||
|
||||
return strcmp(getString(), rhs.getString()) > 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool CrcString::operator >=(CrcString const & rhs) const
|
||||
{
|
||||
return !(*this < rhs);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,66 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrcString.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CrcString_H
|
||||
#define INCLUDED_CrcString_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class CrcString
|
||||
{
|
||||
public:
|
||||
|
||||
static void normalize(char *output, const char *input);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~CrcString();
|
||||
|
||||
bool isEmpty() const;
|
||||
uint32 getCrc() const;
|
||||
|
||||
bool operator ==(CrcString const & rhs) const;
|
||||
bool operator !=(CrcString const & rhs) const;
|
||||
bool DLLEXPORT operator < (CrcString const & rhs) const;
|
||||
bool operator <=(CrcString const & rhs) const;
|
||||
bool operator > (CrcString const & rhs) const;
|
||||
bool operator >=(CrcString const & rhs) const;
|
||||
|
||||
virtual char const * getString() const = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
virtual void set(char const * string, bool applyNormalize) = 0;
|
||||
virtual void set(char const * string, uint32 crc) = 0;
|
||||
void set(CrcString const & rhs);
|
||||
|
||||
protected:
|
||||
|
||||
CrcString();
|
||||
CrcString(uint32 crc);
|
||||
void calculateCrc();
|
||||
|
||||
private:
|
||||
|
||||
CrcString & operator =(CrcString const &);
|
||||
CrcString(CrcString const &);
|
||||
|
||||
protected:
|
||||
|
||||
uint32 m_crc;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline uint32 CrcString::getCrc() const
|
||||
{
|
||||
return m_crc;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,195 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrcStringTable.cpp
|
||||
// Copyright 2003, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/CrcStringTable.h"
|
||||
|
||||
#include "sharedFile/Iff.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
#include "sharedFoundation/ConstCharCrcString.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace CrcStringTableNamespace
|
||||
{
|
||||
const Tag TAG_CSTB = TAG(C,S,T,B);
|
||||
const Tag TAG_CRCT = TAG(C,R,C,T);
|
||||
const Tag TAG_STNG = TAG(S,T,N,G);
|
||||
const Tag TAG_STRT = TAG(S,T,R,T);
|
||||
}
|
||||
using namespace CrcStringTableNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
CrcStringTable::CrcStringTable()
|
||||
:
|
||||
m_numberOfEntries(0),
|
||||
m_crcTable(NULL),
|
||||
m_stringsOffsetTable(NULL),
|
||||
m_strings(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
CrcStringTable::CrcStringTable(char const * fileName)
|
||||
:
|
||||
m_numberOfEntries(0),
|
||||
m_crcTable(NULL),
|
||||
m_stringsOffsetTable(NULL),
|
||||
m_strings(NULL)
|
||||
{
|
||||
load(fileName);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
CrcStringTable::~CrcStringTable()
|
||||
{
|
||||
delete [] m_crcTable;
|
||||
delete [] m_stringsOffsetTable;
|
||||
delete [] m_strings;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void CrcStringTable::load(char const * fileName)
|
||||
{
|
||||
Iff iff;
|
||||
bool result = iff.open(fileName, true);
|
||||
if(!result)
|
||||
{
|
||||
if(fileName)
|
||||
DEBUG_WARNING(true, ("Could not load CrcStringTable %s", fileName));
|
||||
else
|
||||
DEBUG_WARNING(true, ("Could not load CrcStringTable, NULL file given"));
|
||||
return;
|
||||
}
|
||||
|
||||
load(iff);
|
||||
|
||||
#ifdef _DEBUG
|
||||
for (int i = 0; i < m_numberOfEntries; ++i)
|
||||
{
|
||||
const char *string = m_strings + m_stringsOffsetTable[i];
|
||||
uint32 crc = Crc::calculate(string);
|
||||
DEBUG_FATAL(m_crcTable[i] != crc, ("Crcs do not match for %s: %08x %08x", string, m_crcTable[i], crc));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrcStringTable::load(Iff &iff)
|
||||
{
|
||||
iff.enterForm(TAG_CSTB);
|
||||
|
||||
switch (iff.getCurrentName())
|
||||
{
|
||||
case TAG_0000:
|
||||
load_0000(iff);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
char buffer[256];
|
||||
iff.formatLocation(buffer, sizeof(buffer));
|
||||
DEBUG_FATAL(true, ("Unknown crc string table version in %s", buffer));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
iff.exitForm(TAG_CSTB);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrcStringTable::load_0000(Iff &iff)
|
||||
{
|
||||
iff.enterForm(TAG_0000);
|
||||
|
||||
iff.enterChunk(TAG_DATA);
|
||||
m_numberOfEntries = iff.read_int32();
|
||||
iff.exitChunk(TAG_DATA);
|
||||
|
||||
iff.enterChunk(TAG_CRCT);
|
||||
m_crcTable = iff.read_uint32(m_numberOfEntries);
|
||||
iff.exitChunk(TAG_CRCT);
|
||||
|
||||
iff.enterChunk(TAG_STRT);
|
||||
m_stringsOffsetTable = iff.read_int32(m_numberOfEntries);
|
||||
iff.exitChunk(TAG_STRT);
|
||||
|
||||
iff.enterChunk(TAG_STNG);
|
||||
m_strings = iff.readRest_char();
|
||||
iff.exitChunk(TAG_STNG);
|
||||
|
||||
for (int i = 0; i < m_numberOfEntries; ++i)
|
||||
m_crcTable[i] = Crc::calculate(m_strings + m_stringsOffsetTable[i]);
|
||||
|
||||
iff.exitForm(TAG_0000);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcString const CrcStringTable::lookUp(const char * string) const
|
||||
{
|
||||
return lookUp(Crc::calculate(string));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcString const CrcStringTable::lookUp(uint32 crc) const
|
||||
{
|
||||
int low = 0;
|
||||
int high = m_numberOfEntries - 1;
|
||||
|
||||
while (low <= high)
|
||||
{
|
||||
int const mid = (low + high) / 2;
|
||||
uint32 const entry = m_crcTable[mid];
|
||||
if (crc == entry)
|
||||
return ConstCharCrcString(m_strings + m_stringsOffsetTable[mid], crc);
|
||||
else
|
||||
if (crc > entry)
|
||||
low = mid + 1;
|
||||
else
|
||||
high = mid - 1;
|
||||
}
|
||||
|
||||
return ConstCharCrcString("", 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void CrcStringTable::getAllStrings(stdvector<const char *>::fwd & strings) const
|
||||
{
|
||||
strings.reserve(strings.size() + m_numberOfEntries);
|
||||
|
||||
for (int i = 0; i < m_numberOfEntries; ++i)
|
||||
strings.push_back(m_strings + m_stringsOffsetTable[i]);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int CrcStringTable::getNumberOfStrings() const
|
||||
{
|
||||
return m_numberOfEntries;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ConstCharCrcString const CrcStringTable::getString(int const index) const
|
||||
{
|
||||
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfStrings());
|
||||
return ConstCharCrcString(m_strings + m_stringsOffsetTable[index]);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,55 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CrcStringTable.h
|
||||
// Copyright 2003, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CrcStringTable_H
|
||||
#define INCLUDED_CrcStringTable_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ConstCharCrcString;
|
||||
class Iff;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class CrcStringTable
|
||||
{
|
||||
public:
|
||||
|
||||
CrcStringTable();
|
||||
CrcStringTable(const char * fileName);
|
||||
~CrcStringTable();
|
||||
|
||||
void load(const char * fileName);
|
||||
void load(Iff &iff);
|
||||
|
||||
ConstCharCrcString const lookUp(const char * string) const;
|
||||
ConstCharCrcString const lookUp(uint32 crc) const;
|
||||
|
||||
void getAllStrings(stdvector<const char *>::fwd & strings) const;
|
||||
|
||||
int getNumberOfStrings() const;
|
||||
ConstCharCrcString const getString(int index) const;
|
||||
|
||||
private:
|
||||
|
||||
CrcStringTable(CrcStringTable const &);
|
||||
CrcStringTable & operator =(CrcStringTable const &);
|
||||
|
||||
void load_0000(Iff &iff);
|
||||
|
||||
private:
|
||||
|
||||
int m_numberOfEntries;
|
||||
uint32 * m_crcTable;
|
||||
int32 * m_stringsOffsetTable;
|
||||
char * m_strings;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DataResource.cpp - base class for template and other classes.
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/DataResource.h"
|
||||
|
||||
#include "sharedFoundation/PersistentCrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
DataResource::DataResource(const char* const filename) :
|
||||
m_name(filename, true),
|
||||
m_referenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
DataResource::~DataResource()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const char *DataResource::getName() const
|
||||
{
|
||||
return m_name.getString();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int DataResource::getReferenceCount() const
|
||||
{
|
||||
return m_referenceCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DataResource::addReference() const
|
||||
{
|
||||
++m_referenceCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DataResource::releaseReference() const
|
||||
{
|
||||
DEBUG_FATAL(m_referenceCount <= 0, ("DataResource::releaseReference - reference count is already 0\n"));
|
||||
if (m_referenceCount > 0 && --m_referenceCount == 0)
|
||||
release();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DataResource::preloadAssets () const
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DataResource::garbageCollect () const
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,62 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DataResource.h - base class for template and other classes.
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_DataResource_H
|
||||
#define INCLUDED_DataResource_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/PersistentCrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class DataResource
|
||||
{
|
||||
public:
|
||||
|
||||
explicit DataResource(const char* filename);
|
||||
virtual ~DataResource() = 0;
|
||||
|
||||
const char *getName() const;
|
||||
const CrcString &getCrcName() const;
|
||||
|
||||
int getReferenceCount() const;
|
||||
virtual void addReference() const;
|
||||
virtual void releaseReference() const;
|
||||
|
||||
virtual void preloadAssets () const;
|
||||
virtual void garbageCollect () const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void release() const = 0;
|
||||
|
||||
private:
|
||||
|
||||
DataResource ();
|
||||
DataResource(const DataResource &source);
|
||||
DataResource &operator =(const DataResource &source);
|
||||
|
||||
private:
|
||||
|
||||
// resource name
|
||||
const PersistentCrcString m_name;
|
||||
|
||||
// how many times this resource has been loaded
|
||||
mutable int m_referenceCount;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline const CrcString &DataResource::getCrcName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,423 @@
|
||||
//========================================================================
|
||||
//
|
||||
// DataResourceList.h - factory method for creating classes derived from
|
||||
// DataResource.
|
||||
//
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#ifndef _INCLUDED_DataResourceList_H
|
||||
#define _INCLUDED_DataResourceList_H
|
||||
|
||||
#include "sharedDebug/DataLint.h"
|
||||
#include "sharedFile/Iff.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedFoundation/CrcString.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/LessPointerComparator.h"
|
||||
#include "sharedFoundation/Tag.h"
|
||||
#include "sharedFoundation/TemporaryCrcString.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
//========================================================================
|
||||
|
||||
// T should be derived from class DataResource
|
||||
template <typename T>
|
||||
class DataResourceList
|
||||
{
|
||||
public:
|
||||
// DataResource registration function
|
||||
typedef T * (*CreateDataResourceFunc)(const std::string & filename);
|
||||
static void registerTemplate(Tag id, CreateDataResourceFunc createFunc);
|
||||
|
||||
// functions to create a new DataResource
|
||||
static T * fetch(Tag id);
|
||||
static const T * fetch(Iff & source);
|
||||
static const T * fetch(const CrcString & filename);
|
||||
static const T * fetch(const std::string & filename);
|
||||
static const T * fetch(const char * filename);
|
||||
|
||||
static const bool isLoaded(const std::string & fileName);
|
||||
|
||||
// function to reload a data resource with new data
|
||||
static T * reload(Iff & source);
|
||||
|
||||
// functions to reassign Tag->DataResource binding
|
||||
static CreateDataResourceFunc assignBinding(Tag id, CreateDataResourceFunc createFunc);
|
||||
static CreateDataResourceFunc removeBinding(Tag tag);
|
||||
|
||||
static void install(void);
|
||||
static void remove(void);
|
||||
|
||||
// function to delete a DataResource
|
||||
static void release(const T & dataResource);
|
||||
|
||||
static void logLoadedResources(char const * classType);
|
||||
|
||||
static void garbageCollect ();
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<Tag, CreateDataResourceFunc> CreateDataResourceMap;
|
||||
static CreateDataResourceMap *ms_bindings;
|
||||
|
||||
typedef std::map<const CrcString*, const T*, LessPointerComparator> LoadedDataResourceMap;
|
||||
static LoadedDataResourceMap *ms_loaded;
|
||||
|
||||
private:
|
||||
// no copying templates
|
||||
DataResourceList(void);
|
||||
DataResourceList(const DataResourceList &source);
|
||||
DataResourceList & operator =(const DataResourceList &source);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sets up the maps to keep track of resources.
|
||||
*/
|
||||
template <typename T>
|
||||
inline void DataResourceList<T>::install()
|
||||
{
|
||||
if (ms_bindings == NULL)
|
||||
{
|
||||
ms_bindings = new CreateDataResourceMap();
|
||||
ms_loaded = new LoadedDataResourceMap();
|
||||
|
||||
ExitChain::add (remove, "DataResourceList::remove");
|
||||
}
|
||||
} // DataResourceList<T>::install
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Frees up memory associated with the list, and checks for resources still
|
||||
* allocated.
|
||||
*/
|
||||
template <typename T>
|
||||
inline void DataResourceList<T>::remove(void)
|
||||
{
|
||||
if (ms_loaded != NULL)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (!ms_loaded->empty())
|
||||
{
|
||||
DEBUG_REPORT_LOG (true, ("Data resources still allocated:\n"));
|
||||
for (typename LoadedDataResourceMap::const_iterator i = ms_loaded->begin (); i != ms_loaded->end (); ++i)
|
||||
{
|
||||
const T * const dataResource = (*i).second;
|
||||
const int users = dataResource->getReferenceCount ();
|
||||
const char* const name = dataResource->getName ();
|
||||
DEBUG_REPORT_LOG (true, (" %3d %s\n", users, name));
|
||||
UNREF (users);
|
||||
UNREF (name);
|
||||
}
|
||||
|
||||
DEBUG_WARNING (true, ("Data resources still allocated"));
|
||||
return;
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
delete ms_loaded;
|
||||
ms_loaded = NULL;
|
||||
}
|
||||
|
||||
if (ms_bindings != NULL)
|
||||
{
|
||||
delete ms_bindings;
|
||||
ms_bindings = NULL;
|
||||
}
|
||||
} // DataResourceList<T>::remove
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Maps a template Tag id to a function used to create a template.
|
||||
*
|
||||
* @param createFunc template creation function
|
||||
* @param id id of the template
|
||||
*/
|
||||
template <typename T>
|
||||
inline void DataResourceList<T>::registerTemplate(Tag id,
|
||||
CreateDataResourceFunc createFunc)
|
||||
{
|
||||
if (ms_bindings == NULL)
|
||||
install();
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Added to help debug
|
||||
char text[256];
|
||||
ConvertTagToString(id, text);
|
||||
#endif // _DEBUG
|
||||
|
||||
// check if that id was already registered and print a warning if it was
|
||||
if (ms_bindings->find(id) != ms_bindings->end())
|
||||
{
|
||||
char buffer[5];
|
||||
ConvertTagToString(id, buffer);
|
||||
DEBUG_WARNING(true, ("DataResourceList::registerTemplate: re-installing tag %s!", buffer));
|
||||
}
|
||||
(*ms_bindings)[id] = createFunc;
|
||||
} // DataResourceList<T>::registerTemplate
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Changes the default tag->create function binding.
|
||||
*
|
||||
* @param id the tag to change
|
||||
* @param createFunc the creation function to associate with the id
|
||||
*
|
||||
* @return the old creation function associated with the tag
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename DataResourceList<T>::CreateDataResourceFunc DataResourceList<T>::assignBinding(
|
||||
Tag id, CreateDataResourceFunc createFunc)
|
||||
{
|
||||
NOT_NULL(ms_bindings);
|
||||
|
||||
CreateDataResourceFunc oldFunc = (*ms_bindings)[id];
|
||||
(*ms_bindings)[id] = createFunc;
|
||||
return oldFunc;
|
||||
} // DataResourceList<T>::assignBinding
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Removes the default tag->create function binding.
|
||||
*
|
||||
* @param id the tag to remove
|
||||
*
|
||||
* @return the old creation function associated with the tag
|
||||
*/
|
||||
template <typename T>
|
||||
inline typename DataResourceList<T>::CreateDataResourceFunc DataResourceList<T>::removeBinding(
|
||||
Tag id)
|
||||
{
|
||||
NOT_NULL(ms_bindings);
|
||||
|
||||
CreateDataResourceFunc oldFunc = (*ms_bindings)[id];
|
||||
ms_bindings->erase(id);
|
||||
return oldFunc;
|
||||
} // DataResourceList<T>::removeBinding
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
inline const T * DataResourceList<T>::fetch(const std::string & filename)
|
||||
{
|
||||
return fetch(TemporaryCrcString(filename.c_str(), true));
|
||||
} // DataResourceList<T>::fetch(const std::string &)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
inline const T * DataResourceList<T>::fetch(const char * filename)
|
||||
{
|
||||
return fetch(TemporaryCrcString(filename, true));
|
||||
} // DataResourceList<T>::fetch(const char *)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates a data resource from a registered data resource id. The caller is
|
||||
* responsible for deleting the data resource.
|
||||
*
|
||||
* @param id the iff tag for the data resource
|
||||
*
|
||||
* @return the blank data resource
|
||||
*/
|
||||
template <class T>
|
||||
inline T * DataResourceList<T>::fetch(Tag id)
|
||||
{
|
||||
NOT_NULL(ms_bindings);
|
||||
|
||||
typename CreateDataResourceMap::iterator iter = ms_bindings->find(id);
|
||||
if (iter == ms_bindings->end())
|
||||
return NULL;
|
||||
|
||||
return (*(*iter).second)("");
|
||||
} // DataResourceList<T>::fetch(Tag)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Loads a data resource from an iff file/buffer.
|
||||
*
|
||||
* @param source iff source to read from
|
||||
*
|
||||
* @return the data resource
|
||||
*/
|
||||
template <typename T>
|
||||
inline const T * DataResourceList<T>::fetch(Iff &source)
|
||||
{
|
||||
NOT_NULL(ms_bindings);
|
||||
|
||||
#ifdef _DEBUG
|
||||
DataLint::pushAsset(source.getFileName());
|
||||
#endif // _DEBUG
|
||||
|
||||
// read the 1st form; based on the form id, create the template
|
||||
Tag id = source.getCurrentName();
|
||||
typename CreateDataResourceMap::iterator createIter = ms_bindings->find(id);
|
||||
if (createIter == ms_bindings->end())
|
||||
{
|
||||
char buffer[5];
|
||||
ConvertTagToString(id, buffer);
|
||||
DEBUG_WARNING(true, ("DataResourceList::fetch Iff: trying to fetch resource for unknown tag %s!", buffer));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
T *newDataResource = (*(*createIter).second)(source.getFileName());
|
||||
if (newDataResource != NULL)
|
||||
{
|
||||
// initialize the data resource
|
||||
newDataResource->loadFromIff(source);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
DataLint::popAsset();
|
||||
#endif // _DEBUG
|
||||
|
||||
return newDataResource;
|
||||
} // DataResourceList<T>::fetch(Iff &)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Loads a data resource from an iff file.
|
||||
*
|
||||
* @param filename the file to load from
|
||||
*
|
||||
* @return the data resource
|
||||
*/
|
||||
template <typename T>
|
||||
inline const T * DataResourceList<T>::fetch(const CrcString &filename)
|
||||
{
|
||||
NOT_NULL(ms_loaded);
|
||||
|
||||
// see if we already have loaded the template
|
||||
typename LoadedDataResourceMap::iterator iter = ms_loaded->find(&filename);
|
||||
if (iter != ms_loaded->end())
|
||||
{
|
||||
(*iter).second->addReference();
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
// load the template
|
||||
Iff iff;
|
||||
if (!iff.open(filename.getString(), true))
|
||||
return NULL;
|
||||
|
||||
// put the template in the loaded list
|
||||
const T * const newDataResource = fetch(iff);
|
||||
if (newDataResource != NULL)
|
||||
{
|
||||
newDataResource->addReference();
|
||||
ms_loaded->insert(std::make_pair(&newDataResource->getCrcName (), newDataResource));
|
||||
}
|
||||
|
||||
// clean up
|
||||
iff.close();
|
||||
return newDataResource;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks the reference count of a resource, if it is 0, deletes it.
|
||||
*
|
||||
* @param dataResource the data resource to release
|
||||
*/
|
||||
template <typename T>
|
||||
inline void DataResourceList<T>::release(const T & dataResource)
|
||||
{
|
||||
NOT_NULL(ms_loaded);
|
||||
|
||||
if (ms_loaded != NULL && dataResource.getReferenceCount() == 0)
|
||||
{
|
||||
typename LoadedDataResourceMap::iterator iter = ms_loaded->find(&dataResource.getCrcName());
|
||||
if (iter != ms_loaded->end())
|
||||
{
|
||||
const T * const temp = (*iter).second;
|
||||
(*iter).second = NULL;
|
||||
ms_loaded->erase(iter);
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
} // DataResourceList<T>::release
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Reloads a data resource from an iff file/buffer.
|
||||
*
|
||||
* @param source iff source to read from
|
||||
*
|
||||
* @return the data resource
|
||||
*/
|
||||
template <typename T>
|
||||
inline T * DataResourceList<T>::reload(Iff &source)
|
||||
{
|
||||
NOT_NULL(ms_loaded);
|
||||
|
||||
const TemporaryCrcString sourceCrcString (source.getFileName(), true);
|
||||
typename LoadedDataResourceMap::iterator iter = ms_loaded->find(&sourceCrcString);
|
||||
if (iter == ms_loaded->end())
|
||||
{
|
||||
DEBUG_WARNING(true, ("DataResourceList::reload: trying to reload unloaded resource %s!", source.getFileName()));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
T * const dataResource = const_cast<T *>((*iter).second);
|
||||
if (dataResource != NULL)
|
||||
{
|
||||
// initialize the data resource
|
||||
dataResource->loadFromIff(source);
|
||||
}
|
||||
return dataResource;
|
||||
} // DataResourceList<T>::reload(Iff &)
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
inline const bool DataResourceList<T>::isLoaded(const std::string & source)
|
||||
{
|
||||
NOT_NULL(ms_loaded);
|
||||
const TemporaryCrcString sourceCrcString (source.c_str (), true);
|
||||
typename LoadedDataResourceMap::iterator iter = ms_loaded->find(&sourceCrcString);
|
||||
return (iter != ms_loaded->end());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
void DataResourceList<T>::logLoadedResources(char const * classType)
|
||||
{
|
||||
UNREF(classType); //necessary for release build
|
||||
typename LoadedDataResourceMap::iterator const iterEnd = ms_loaded->end();
|
||||
DEBUG_REPORT_LOG_PRINT(true, ("Begin log of loaded %s\n", classType));
|
||||
|
||||
for (typename LoadedDataResourceMap::iterator iter = ms_loaded->begin(); iter != iterEnd; ++iter)
|
||||
DEBUG_REPORT_LOG_PRINT(true, (" %d %s\n", iter->second->getReferenceCount(), iter->second->getName()));
|
||||
|
||||
DEBUG_REPORT_LOG_PRINT(true, ("End log of loaded %s\n", classType));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
void DataResourceList<T>::garbageCollect ()
|
||||
{
|
||||
typename LoadedDataResourceMap::iterator end = ms_loaded->end ();
|
||||
typename LoadedDataResourceMap::iterator iter = ms_loaded->begin ();
|
||||
for (; iter != end; ++iter)
|
||||
const_cast<T*> (iter->second)->garbageCollect ();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_DataResourceList_H
|
||||
@@ -0,0 +1,127 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DebugInfoManager.cpp
|
||||
// Copyright 2005 Sony Online Entertainment Inc
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/DebugInfoManager.h"
|
||||
|
||||
#include "sharedMath/Transform.h"
|
||||
#include "sharedMath/Vector.h"
|
||||
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace DebugInfoManagerNamespace
|
||||
{
|
||||
char ms_buffer[256];
|
||||
|
||||
Unicode::String const cms_emptyQuotes(Unicode::narrowToWide("\"\""));
|
||||
}
|
||||
using namespace DebugInfoManagerNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, int const propertyValue)
|
||||
{
|
||||
_itoa(propertyValue, ms_buffer, 10);
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(ms_buffer));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, float const propertyValue)
|
||||
{
|
||||
sprintf(ms_buffer, "%.2f", propertyValue);
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(ms_buffer));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, unsigned int const propertyValue)
|
||||
{
|
||||
sprintf(ms_buffer, "%u", propertyValue);
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(ms_buffer));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, unsigned long const propertyValue)
|
||||
{
|
||||
sprintf(ms_buffer, "%lu", propertyValue);
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(ms_buffer));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, bool const propertyValue)
|
||||
{
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(propertyValue ? "true" : "false"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, std::string const & propertyValue)
|
||||
{
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(propertyValue));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, char const * const propertyValue)
|
||||
{
|
||||
if(propertyValue)
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(propertyValue));
|
||||
else
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(""));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, Vector const & propertyValue)
|
||||
{
|
||||
sprintf(ms_buffer, "(%.2f, %.2f, %.2f)", propertyValue.x, propertyValue.y, propertyValue.z);
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(ms_buffer));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, Transform const & propertyValue)
|
||||
{
|
||||
Transform::matrix_t const & matrix = propertyValue.getMatrix();
|
||||
sprintf(ms_buffer, "\n\t\t[[%.2f, %.2f, %.2f, %.2f]\n\t\t[%.2f, %.2f, %.2f, %.2f]\n\t\t[%.2f, %.2f, %.2f, %.2f]]", matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3], matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3], matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3]);
|
||||
addProperty(propertyMap, section, propertyName, Unicode::narrowToWide(ms_buffer));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void DebugInfoManager::addProperty(DebugInfoManager::PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, Unicode::String const & propertyValue)
|
||||
{
|
||||
//okay to create entry if the section doesn't exist;
|
||||
PropertySection sectionMap = propertyMap[section];
|
||||
|
||||
if(sectionMap.find(propertyName) == sectionMap.end())
|
||||
{
|
||||
if(!propertyValue.empty())
|
||||
sectionMap[propertyName] = propertyValue;
|
||||
else
|
||||
sectionMap[propertyName] = cms_emptyQuotes;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!propertyValue.empty())
|
||||
sectionMap[propertyName + "_a"] = propertyValue;
|
||||
else
|
||||
sectionMap[propertyName + "_a"] = cms_emptyQuotes;
|
||||
}
|
||||
|
||||
propertyMap[section] = sectionMap;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,46 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// DebugInfoManager.h
|
||||
// Copyright 2004 Sony Online Entertainment Inc
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_DebugInfoManager_H
|
||||
#define INCLUDED_DebugInfoManager_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Transform;
|
||||
class Vector;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class DebugInfoManager
|
||||
{
|
||||
public:
|
||||
typedef stdmap<std::string, Unicode::String>::fwd PropertySection;
|
||||
typedef stdmap<std::string, PropertySection>::fwd PropertyMap;
|
||||
|
||||
public:
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, int propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, unsigned int propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, unsigned long propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, float propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, bool propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, std::string const & propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, char const * propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, Transform const & propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, Vector const & propertyValue);
|
||||
static void addProperty(PropertyMap & propertyMap, std::string const & section, std::string const & propertyName, Unicode::String const & propertyValue);
|
||||
|
||||
private:
|
||||
DebugInfoManager();
|
||||
~DebugInfoManager();
|
||||
DebugInfoManager(DebugInfoManager const &);
|
||||
DebugInfoManager & operator=(DebugInfoManager const &);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,271 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ExitChain.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
|
||||
#include "sharedDebug/DebugFlags.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool ExitChain::ms_debugReportFlag;
|
||||
bool ExitChain::ms_debugLogFlag;
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void ExitChain::install()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
DebugFlags::registerFlag(ms_debugReportFlag, "SharedFoundation", "reportExitChain", &ExitChain::debugReport);
|
||||
DebugFlags::registerFlag(ms_debugLogFlag, "SharedFoundation", "logExitChain");
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ExitChain::quit()
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// Check if the ExitChain is running or not
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// True if ExitChain::quit() or ExitChain::fatal() has been called
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// If the result is true, the application is terminating.
|
||||
//
|
||||
// See Also:
|
||||
//
|
||||
// ExitChain::quit(), ExitChain:fatal(), ExitChain::isFataling()
|
||||
|
||||
bool ExitChain::isRunning(void)
|
||||
{
|
||||
return PerThreadData::getExitChainRunning();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Check if the ExitChain is fataling or not.
|
||||
*
|
||||
* If the ExitChain is fataling, minimal cleanup work should be done to restore the users system to a usable
|
||||
* state. If this routine returns true, ExitChain::isRunning() will also return true.
|
||||
*
|
||||
* @return True if the ExitChain::fatal() has been called
|
||||
* @see ExitChain::isRunning()
|
||||
*/
|
||||
|
||||
bool ExitChain::isFataling(void)
|
||||
{
|
||||
return PerThreadData::getExitChainFataling();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Add a function to the ExitChain to be called when the game exits.
|
||||
*
|
||||
* The order of the function calls depends on priority and the order in which they are added to the
|
||||
* ExitChain. See the main ExitChain documentation for more details.
|
||||
*
|
||||
* @param function The function to call
|
||||
* @param debugName Text description of the function (for debugging purposes only)
|
||||
* @param priority Priority of the function for proper shutdown ordering
|
||||
* @param critical Flag to indicate the function should be called even when fataling
|
||||
* @see ExitChain
|
||||
*/
|
||||
|
||||
void ExitChain::add(Function function, const char *debugName, int priority, bool critical)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
//-- Verify that the entry doesn't already exist in the ExitChain
|
||||
{
|
||||
for (Entry * entry = PerThreadData::getExitChainFirstEntry(); entry; entry = entry->next)
|
||||
{
|
||||
if (entry->function == function)
|
||||
{
|
||||
DEBUG_WARNING(true, ("ExitChain::add: %s is already in the list", debugName));
|
||||
entry->m_callStack.debugLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Entry *entry, *back, *front;
|
||||
|
||||
// create the new ExitChain entry
|
||||
entry = new Entry;
|
||||
entry->function = function;
|
||||
entry->name = debugName;
|
||||
entry->priority = priority;
|
||||
entry->critical = critical;
|
||||
#ifdef _DEBUG
|
||||
entry->m_callStack.sample();
|
||||
#endif
|
||||
|
||||
// linked list traversal with a back pointer
|
||||
for (back = NULL, front = PerThreadData::getExitChainFirstEntry(); front && front->priority > priority; back = front, front = front->next)
|
||||
;
|
||||
|
||||
// hook it into the linked list
|
||||
entry->next = front;
|
||||
if (back)
|
||||
back->next = entry;
|
||||
else
|
||||
PerThreadData::setExitChainFirstEntry(entry);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Remove a function from the ExitChain.
|
||||
*
|
||||
* The ExitChain will automatically remove a function from the ExitChain when it calls the function, so an
|
||||
* exit function should not attempt to remove itself from the ExitChain.
|
||||
*
|
||||
* Calling this routine with a NULL pointer will cause this routine to call Fatal in debug compilations.
|
||||
*
|
||||
* Calling this routine with a function that is not on the ExitChain will cause this routine to call
|
||||
* Fatal in debug compilations.
|
||||
*
|
||||
* @param function The function to remove from the ExitChain list
|
||||
*/
|
||||
|
||||
void ExitChain::remove(Function function)
|
||||
{
|
||||
Entry *back, *front;
|
||||
|
||||
if (function == NULL)
|
||||
{
|
||||
DEBUG_FATAL(true, ("ExitChain::remove NULL function"));
|
||||
return; //lint !e527 // Warning -- Unreachable
|
||||
}
|
||||
|
||||
// linked list traversal with a back pointer
|
||||
for (back = NULL, front = PerThreadData::getExitChainFirstEntry(); front && front->function != function; back = front, front = front->next)
|
||||
;
|
||||
|
||||
// make sure it was found
|
||||
if (!front)
|
||||
{
|
||||
DEBUG_FATAL(true, ("ExitChain::remove function not found %p", function));
|
||||
return; //lint !e527 // Warning -- Unreachable
|
||||
}
|
||||
|
||||
// remove from the linked list
|
||||
if (back)
|
||||
back->next = front->next;
|
||||
else
|
||||
PerThreadData::setExitChainFirstEntry(front->next);
|
||||
|
||||
// free the memory associated with this entry
|
||||
delete front;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Process the exit chain.
|
||||
*
|
||||
* This routine is protected against re-entry so that the ExitChain routines can call Fatal and behave
|
||||
* properly.
|
||||
*
|
||||
* @see Fatal()
|
||||
*/
|
||||
|
||||
void ExitChain::run(void)
|
||||
{
|
||||
Entry *entry;
|
||||
|
||||
if (isRunning())
|
||||
return;
|
||||
|
||||
PerThreadData::setExitChainRunning(true);
|
||||
|
||||
while ((entry = PerThreadData::getExitChainFirstEntry()) != NULL)
|
||||
{
|
||||
// remove the first entry off the ExitChain
|
||||
PerThreadData::setExitChainFirstEntry(entry->next);
|
||||
|
||||
// call the function if it's critical or we're not fataling
|
||||
if (entry->critical || !isFataling())
|
||||
{
|
||||
DEBUG_REPORT_LOG_PRINT(ms_debugLogFlag, ("ExitChain::run >> %s\n", entry->name));
|
||||
DEBUG_OUTPUT_CHANNEL("Foundation\\Exitchain", ("ExitChain::run >> %s\n", entry->name));
|
||||
entry->function();
|
||||
DEBUG_REPORT_LOG_PRINT(ms_debugLogFlag, ("ExitChain::run << %s\n", entry->name));
|
||||
DEBUG_OUTPUT_CHANNEL("Foundation\\Exitchain", ("ExitChain::run << %s\n", entry->name));
|
||||
}
|
||||
|
||||
// free the memory if we're not fataling
|
||||
if (!isFataling())
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Clean up the game due to an abnormal condition.
|
||||
*
|
||||
* This routine should only be called by Fatal(). It is not intended for any other use.
|
||||
*
|
||||
* @see ExitChain::quit(), Fatal()
|
||||
*/
|
||||
|
||||
void ExitChain::fatal(void)
|
||||
{
|
||||
if (PerThreadData::isThreadInstalled())
|
||||
{
|
||||
PerThreadData::setExitChainFataling(true);
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Dump the contents of the ExitChain to the DebugMonitor.
|
||||
*
|
||||
* This routine is for debugging only.
|
||||
*
|
||||
* @param logMessage Log to the debugger as well
|
||||
*/
|
||||
|
||||
void ExitChain::debugReport(bool logMessage)
|
||||
{
|
||||
UNREF(logMessage);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
DEBUG_OUTPUT_STATIC_VIEW_BEGINFRAME("Foundation\\Exitchain");
|
||||
for (Entry *entry = PerThreadData::getExitChainFirstEntry(); entry; entry = entry->next)
|
||||
{
|
||||
DEBUG_REPORT(true, Report::RF_print | (logMessage ? Report::RF_log : 0), ("%4d=pri %d=crit %p=func %s\n", entry->priority, static_cast<int>(entry->critical), entry->function, entry->name));
|
||||
DEBUG_OUTPUT_STATIC_VIEW("Foundation\\Exitchain", ("%4d=pri %d=crit %p=func %s\n", entry->priority, static_cast<int>(entry->critical), entry->function, entry->name));
|
||||
}
|
||||
DEBUG_OUTPUT_STATIC_VIEW_ENDFRAME("Foundation\\Exitchain");
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Dump the contents of the ExitChain to the DebugMonitor.
|
||||
*
|
||||
* This routine is for debugging only.
|
||||
*/
|
||||
|
||||
void ExitChain::debugReport()
|
||||
{
|
||||
debugReport(false);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ExitChain.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// Maintains a list of functions to call at game exit time for cleanup.
|
||||
//
|
||||
// Functions are first in order of priority, with the higher interger priority functions being called
|
||||
// first. For functions with the same priority, they are called in the opposite order that they were
|
||||
// added to the ExitChain, in a last-in-first-out (LIFO) manner.
|
||||
//
|
||||
// When the ExitChain is running because fatal() was called, only the entries that have their critical flag
|
||||
// set true will be called.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef EXIT_CHAIN_H
|
||||
#define EXIT_CHAIN_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedDebug/CallStack.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class ExitChain
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void (*Function)(void);
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Entry *next;
|
||||
Function function;
|
||||
const char *name;
|
||||
int priority;
|
||||
bool critical;
|
||||
#ifdef _DEBUG
|
||||
CallStack m_callStack;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
// disabled
|
||||
ExitChain(void);
|
||||
ExitChain(const ExitChain &);
|
||||
ExitChain &operator =(const ExitChain &);
|
||||
|
||||
private:
|
||||
|
||||
static void run(void);
|
||||
|
||||
private:
|
||||
|
||||
#ifdef _DEBUG
|
||||
static bool ms_debugReportFlag;
|
||||
static bool ms_debugLogFlag;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void quit();
|
||||
static void fatal();
|
||||
|
||||
static void add(Function function, const char *debugName, int priority=0, bool critical=false);
|
||||
static void remove(Function function);
|
||||
|
||||
|
||||
static bool isRunning(void);
|
||||
static DLLEXPORT bool isFataling(void);
|
||||
|
||||
static void debugReport();
|
||||
static void debugReport(bool log);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Fatal.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Fatal.h"
|
||||
|
||||
#include "sharedDebug/DataLint.h"
|
||||
#include "sharedDebug/DebugHelp.h"
|
||||
#include "sharedDebug/PixCounter.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/PerThreadData.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace FatalNamespace
|
||||
{
|
||||
Mutex ms_criticalSection;
|
||||
char ms_buffer[32 * 1024];
|
||||
bool ms_throwExceptions;
|
||||
int ms_numberOfWarnings = 0;
|
||||
bool ms_strict = false;
|
||||
|
||||
WarningCallback s_warningCallback = NULL;
|
||||
|
||||
#if PRODUCTION == 0
|
||||
PixCounter::ResetInteger ms_numberOfWarningsThisFrame;
|
||||
#endif
|
||||
}
|
||||
using namespace FatalNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void FatalInstall()
|
||||
{
|
||||
#if PRODUCTION == 0
|
||||
ms_numberOfWarningsThisFrame.bindToCounter("Warnings");
|
||||
#endif
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
static void formatMessage(char *buffer, int bufferLength, int stackDepth, const char *type, const char *format, va_list va)
|
||||
{
|
||||
const int callStackOffset = 4;
|
||||
const int maxStackDepth = 64;
|
||||
|
||||
if (stackDepth > maxStackDepth)
|
||||
stackDepth = maxStackDepth;
|
||||
|
||||
// look up the call stack information
|
||||
const int callStackSize = callStackOffset + stackDepth;
|
||||
uint32 callStack[callStackOffset + maxStackDepth];
|
||||
|
||||
// allow complete disable of the call stack lookup
|
||||
if (stackDepth < 0)
|
||||
memset(callStack, 0, sizeof(callStack));
|
||||
else
|
||||
DebugHelp::getCallStack(callStack, callStackOffset + stackDepth);
|
||||
|
||||
// make sure the buffer is always null terminated
|
||||
buffer[--bufferLength] = '\0';
|
||||
|
||||
// look up the caller's file and line
|
||||
if (callStack[callStackOffset])
|
||||
{
|
||||
char lib[4 * 1024] = { '\0' };
|
||||
char file[4 * 1024] = { '\0' };
|
||||
int line = 0;
|
||||
if (ConfigSharedFoundation::getLookUpCallStackNames() && DebugHelp::lookupAddress(callStack[callStackOffset], lib, file, sizeof(file), line))
|
||||
snprintf(buffer, bufferLength, "%s(%d) : %s %08x: ", file, line, type, static_cast<int>(Crc::calculate(format)));
|
||||
else
|
||||
snprintf(buffer, bufferLength, "unknown(0x%08X) : %s %08x: ", static_cast<int>(callStack[callStackOffset]), type, static_cast<int>(Crc::calculate(format)));
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buffer, bufferLength, "unknown location : %s %08x: ", type, static_cast<int>(Crc::calculate(format)));
|
||||
}
|
||||
|
||||
{
|
||||
const int length = strlen(buffer);
|
||||
buffer += length;
|
||||
bufferLength -= length;
|
||||
}
|
||||
|
||||
// add the user message
|
||||
vsnprintf(buffer, bufferLength, format, va);
|
||||
|
||||
{
|
||||
const int length = strlen(buffer);
|
||||
buffer += length;
|
||||
bufferLength -= length;
|
||||
}
|
||||
|
||||
// add the newline
|
||||
if (bufferLength)
|
||||
{
|
||||
*buffer = '\n';
|
||||
++buffer;
|
||||
--bufferLength;
|
||||
*buffer = '\0';
|
||||
}
|
||||
|
||||
if (stackDepth >= 0)
|
||||
{
|
||||
// add the call stack
|
||||
for (int i = callStackOffset+1; i < callStackSize; ++i)
|
||||
if (callStack[i])
|
||||
{
|
||||
char lib[1024];
|
||||
char file[1024];
|
||||
int line = 0;
|
||||
|
||||
if (ConfigSharedFoundation::getLookUpCallStackNames() && DebugHelp::lookupAddress(callStack[i], lib, file, sizeof(file), line))
|
||||
snprintf(buffer, bufferLength, " %s(%d) : caller %d\n", file, line, i-callStackOffset);
|
||||
else
|
||||
snprintf(buffer, bufferLength, " unknown(0x%08X) : caller %d\n", static_cast<int>(callStack[i]), i-callStackOffset);
|
||||
|
||||
const int length = strlen(buffer);
|
||||
buffer += length;
|
||||
bufferLength -= length;
|
||||
}
|
||||
}
|
||||
|
||||
if (bufferLength == 0)
|
||||
{
|
||||
buffer[-2] = '+';
|
||||
buffer[-1] = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Terminate the game due to an abnormal condition.
|
||||
*
|
||||
* This routine does not return.
|
||||
*
|
||||
* This routine will call ExitChain::fatal() to clean up the system as appropriate.
|
||||
*
|
||||
* @param format printf-style formatting string
|
||||
* @see PreFatal()
|
||||
*/
|
||||
|
||||
static void InternalFatal(const char *format, va_list va)
|
||||
{
|
||||
// if the per-thread-data isn't installed, then we know we're single-threaded and can use the static buffer
|
||||
ms_criticalSection.enter();
|
||||
const int bufferSize = sizeof(ms_buffer);
|
||||
const int length = strlen(ms_buffer);
|
||||
formatMessage(ms_buffer+length, bufferSize-length, ConfigSharedFoundation::getFatalCallStackDepth(), "FATAL", format, va);
|
||||
ms_criticalSection.leave();
|
||||
|
||||
REPORT(true, Report::RF_print | Report::RF_log | Report::RF_fatal, ("%s", ms_buffer));
|
||||
|
||||
IGNORE_RETURN(Os::copyTextToClipboard(ms_buffer));
|
||||
|
||||
if (ms_throwExceptions)
|
||||
throw FatalException(ms_buffer, FatalException::ZeroSourceString); //lint !e1549 // Function not declared to throw
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
__asm int 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUG_OUTPUT_CHANNEL("Foundation\\Fatal", ("%s", ms_buffer));
|
||||
ExitChain::fatal();
|
||||
REPORT(true, Report::RF_fatal | Report::RF_dialog, ("%s", ms_buffer));
|
||||
Os::abort();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static void InternalWarning(const char *format, int extraFlags, va_list va, int stackDepth = ConfigSharedFoundation::getWarningCallStackDepth())
|
||||
{
|
||||
#if PRODUCTION == 0
|
||||
++ms_numberOfWarningsThisFrame;
|
||||
#endif
|
||||
|
||||
char buffer[4 * 1024];
|
||||
|
||||
if (NULL != s_warningCallback)
|
||||
{
|
||||
strcpy(buffer, "WARNING: ");
|
||||
vsnprintf(buffer + 9, sizeof(buffer) - 9, format, va);
|
||||
strcat(buffer, "\n");
|
||||
s_warningCallback(buffer);
|
||||
}
|
||||
|
||||
formatMessage(buffer, sizeof(buffer), stackDepth, "WARNING", format, va);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (DataLint::isInstalled())
|
||||
{
|
||||
DataLint::logWarning(buffer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
++ms_numberOfWarnings;
|
||||
REPORT(true, Report::RF_print | Report::RF_log | Report::RF_warning | extraFlags, ("%s", buffer));
|
||||
DEBUG_OUTPUT_CHANNEL("Foundation\\Warning", ("%s", buffer));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void SetWarningCallback(WarningCallback warningCallback)
|
||||
{
|
||||
s_warningCallback = warningCallback;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
FatalException::FatalException(char *newMessage, Zero zero)
|
||||
: message(DuplicateString(newMessage))
|
||||
{
|
||||
UNREF(zero);
|
||||
if (newMessage)
|
||||
newMessage[0] = '\0';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
FatalException::FatalException(const FatalException &fatalException)
|
||||
: message(DuplicateString(fatalException.message))
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
FatalException::~FatalException(void)
|
||||
{
|
||||
delete [] message;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
FatalException &FatalException::operator =(const FatalException &fatalException)
|
||||
{
|
||||
if (&fatalException != this)
|
||||
{
|
||||
delete [] message;
|
||||
message = DuplicateString(fatalException.message);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const char *FatalException::getMessage(void) const
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void FatalSetVersionString(const char *string)
|
||||
{
|
||||
strcat(ms_buffer, string);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void FatalSetThrowExceptions(bool throwExceptions)
|
||||
{
|
||||
ms_throwExceptions = throwExceptions;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int GetNumberOfWarnings()
|
||||
{
|
||||
return ms_numberOfWarnings;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Fatal(const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
InternalFatal(format, va);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
void DebugFatal(const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
InternalFatal(format, va);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Warning(const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
InternalWarning(format, 0, va);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void WarningStackDepth(int stackDepth, const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
InternalWarning(format, 0, va, stackDepth);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ConsoleWarning(const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
InternalWarning(format, Report::RF_console, va);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void SetWarningStrictFatal(bool strict)
|
||||
{
|
||||
ms_strict = strict;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool GetWarningStrictFatal()
|
||||
{
|
||||
return ms_strict;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void WarningStrictFatal(const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
if (ms_strict)
|
||||
InternalFatal(format, va);
|
||||
else
|
||||
InternalWarning(format, 0, va);
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,162 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Fatal.h
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Fatal_H
|
||||
#define INCLUDED_Fatal_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void FatalInstall();
|
||||
|
||||
void FatalSetVersionString(const char *string);
|
||||
void FatalSetThrowExceptions(bool throwExceptions);
|
||||
DLLEXPORT void Fatal(const char *format, ...);
|
||||
|
||||
DLLEXPORT void DebugFatal(const char *format, ...);
|
||||
|
||||
int GetNumberOfWarnings(void);
|
||||
DLLEXPORT void Warning(const char *format, ...);
|
||||
DLLEXPORT void WarningStackDepth(int stackDepth, const char *format, ...);
|
||||
DLLEXPORT void ConsoleWarning(const char *format, ...);
|
||||
|
||||
void SetWarningStrictFatal(bool fatal);
|
||||
bool GetWarningStrictFatal();
|
||||
DLLEXPORT void WarningStrictFatal(const char *format, ...);
|
||||
|
||||
typedef void (*WarningCallback) (char const * const);
|
||||
void SetWarningCallback(WarningCallback);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define FATAL(a, b) ((a) ? Fatal b : NOP)
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG_FATAL(a, b) ((a) ? DebugFatal b : NOP)
|
||||
#else
|
||||
#define DEBUG_FATAL(a, b) NOP
|
||||
#endif
|
||||
|
||||
#define WARNING(a, b) ((a) ? Warning b : NOP)
|
||||
#define WARNING_STACK_DEPTH(a, b) ((a) ? WarningStackDepth b : NOP)
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG_WARNING(a, b) WARNING(a, b)
|
||||
#else
|
||||
#define DEBUG_WARNING(a, b) NOP
|
||||
#endif
|
||||
|
||||
#define CONSOLE_WARNING(a, b) ((a) ? ConsoleWarning b : NOP)
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG_CONSOLE_WARNING(a, b) CONSOLE_WARNING(a, b)
|
||||
#else
|
||||
#define DEBUG_CONSOLE_WARNING(a, b) NOP
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define WARNING_DEBUG_FATAL(a, b) DEBUG_FATAL(a, b)
|
||||
#else
|
||||
#define WARNING_DEBUG_FATAL(a, b) WARNING(a, b)
|
||||
#endif
|
||||
|
||||
#define WARNING_STRICT_FATAL(a, b) ((a) ? WarningStrictFatal b : NOP)
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
template <class T>
|
||||
inline T *NonNull(T *pointer, const char *name)
|
||||
{
|
||||
FATAL(!pointer, ("%s pointer is null", name));
|
||||
return pointer;
|
||||
}
|
||||
|
||||
#define NON_NULL(a) NonNull(a, #a)
|
||||
#define NOT_NULL(a) FATAL(!a, ("%s pointer is null", #a))
|
||||
|
||||
// FATAL if the specified pointer is not NULL (i.e. assert that the pointer is null, the opposite of NOT_NULL).
|
||||
#define IS_NULL(a) FATAL(a, ("%s pointer is not null, unexpected.", #a))
|
||||
|
||||
#else
|
||||
|
||||
#define NON_NULL(a) (a)
|
||||
#define NOT_NULL(a) UNREF(a)
|
||||
|
||||
#define IS_NULL(a) UNREF(a)
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Fatal if the specified var does not satisfy (low <= var < high).
|
||||
*
|
||||
* The parameter types must be integral and must be convertable to
|
||||
* an int.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline void ValidateRangeInclusiveExclusive(const T &low, const T &var, const T &high, const char *varName)
|
||||
{
|
||||
FATAL(low > high, ("range check low [%d] > high [%d]", static_cast<int>(low), static_cast<int>(high)));
|
||||
FATAL( (var < low) || (var >= high), ("%s [%d] out of valid range [%d..%d)", varName, static_cast<int>(var), static_cast<int>(low), static_cast<int>(high)));
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(low, var, high) ValidateRangeInclusiveExclusive(low, var, high, #var)
|
||||
#else
|
||||
#define VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(low, var, high) NOP
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Fatal if the specified var does not satisfy (low <= var <= high).
|
||||
*
|
||||
* The parameter types must be integral and must be convertable to
|
||||
* an int.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
inline void ValidateRangeInclusiveInclusive(const T &low, const T &var, const T &high, const char *varName)
|
||||
{
|
||||
FATAL(low > high, ("range check low [%d] > high [%d]", static_cast<int>(low), static_cast<int>(high)));
|
||||
FATAL( (var < low) || (var > high), ("%s [%d] out of valid range [%d..%d]", varName, static_cast<int>(var), static_cast<int>(low), static_cast<int>(high)));
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define VALIDATE_RANGE_INCLUSIVE_INCLUSIVE(low, var, high) ValidateRangeInclusiveInclusive(low, var, high, #var)
|
||||
#else
|
||||
#define VALIDATE_RANGE_INCLUSIVE_INCLUSIVE(low, var, high) NOP
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class FatalException
|
||||
{
|
||||
public:
|
||||
|
||||
enum Zero
|
||||
{
|
||||
ZeroSourceString
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
char *message;
|
||||
|
||||
public:
|
||||
|
||||
FatalException(char *newMessage, Zero zero);
|
||||
FatalException(const FatalException &fatalException);
|
||||
~FatalException(void);
|
||||
|
||||
FatalException &operator =(const FatalException &fatalException);
|
||||
|
||||
const char *getMessage(void) const;
|
||||
};
|
||||
|
||||
struct _EXCEPTION_POINTERS;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstSharedFoundation.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FirstSharedFoundation_H
|
||||
#define INCLUDED_FirstSharedFoundation_H
|
||||
|
||||
// ======================================================================
|
||||
// Set the different build debug levels
|
||||
|
||||
#define DEBUG_LEVEL_RELEASE 0
|
||||
#define DEBUG_LEVEL_OPTIMIZED 1
|
||||
#define DEBUG_LEVEL_DEBUG 2
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
|
||||
#ifndef DEBUG_LEVEL
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG_LEVEL DEBUG_LEVEL_DEBUG
|
||||
#else
|
||||
#define DEBUG_LEVEL DEBUG_LEVEL_RELEASE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (DEBUG_LEVEL != DEBUG_LEVEL_RELEASE) && (DEBUG_LEVEL != DEBUG_LEVEL_OPTIMIZED) && (DEBUG_LEVEL != DEBUG_LEVEL_DEBUG)
|
||||
#error DEBUG_LEVEL is not valid
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
// things we really have to have
|
||||
|
||||
#include "sharedFoundationTypes/FoundationTypes.h"
|
||||
#include "sharedFoundation/FirstPlatform.h"
|
||||
#include "sharedMemoryManager/MemoryManager.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
// ======================================================================
|
||||
// deprecated stuff that should eventually go away
|
||||
|
||||
typedef float real;
|
||||
|
||||
#define CONST_REAL(a) static_cast<float>(a)
|
||||
#define RECIP(a) (1.0f / (a))
|
||||
|
||||
const float REAL_MIN = FLT_MIN;
|
||||
const float REAL_MAX = FLT_MAX;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
// @todo codereorg
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 260
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
// things that are useful just about everywhere
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "sharedFoundation/MacroFoundation.h"
|
||||
|
||||
#include "sharedFoundation/Binary.h"
|
||||
#include "sharedFoundation/Fatal.h"
|
||||
#include "sharedFoundation/StlForwardDeclaration.h"
|
||||
#include "sharedFoundation/Misc.h"
|
||||
#include "sharedDebug/RemoteDebug.h"
|
||||
#include "sharedDebug/Report.h"
|
||||
#include "sharedFoundation/FloatMath.h"
|
||||
#include "sharedFoundation/SafeCast.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,167 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FloatMath.h
|
||||
// Portions Copyright 1998 Bootprint Entertainment
|
||||
// Portions Copyright 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FloatMath_H
|
||||
#define INCLUDED_FloatMath_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
float const PI = 3.14159265358979323846f;
|
||||
float const PI_TIMES_2 = PI * 2.0f;
|
||||
float const PI_OVER_2 = PI / 2.0f;
|
||||
float const PI_OVER_3 = PI / 3.0f;
|
||||
float const PI_OVER_4 = PI / 4.0f;
|
||||
float const PI_OVER_6 = PI / 6.0f;
|
||||
float const PI_OVER_8 = PI / 8.0f;
|
||||
float const PI_OVER_12 = PI / 12.0f;
|
||||
float const PI_OVER_16 = PI / 16.0f;
|
||||
float const PI_OVER_180 = PI / 180.0f;
|
||||
|
||||
float const E = 2.7182818284590452f;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
|
||||
#if _MSC_VER < 1300
|
||||
|
||||
inline float abs(float f)
|
||||
{
|
||||
return fabsf(f);
|
||||
}
|
||||
|
||||
inline float sqrt(float f)
|
||||
{
|
||||
return sqrtf(f);
|
||||
}
|
||||
|
||||
inline float sin(float f)
|
||||
{
|
||||
return sinf(f);
|
||||
}
|
||||
|
||||
inline float cos(float f)
|
||||
{
|
||||
return cosf(f);
|
||||
}
|
||||
|
||||
inline float tan(float f)
|
||||
{
|
||||
return tanf(f);
|
||||
}
|
||||
|
||||
inline float asin(float f)
|
||||
{
|
||||
return asinf(f);
|
||||
}
|
||||
|
||||
inline float acos(float f)
|
||||
{
|
||||
return acosf(f);
|
||||
}
|
||||
|
||||
inline float atan2(float y, float x)
|
||||
{
|
||||
return atan2f(y, x);
|
||||
}
|
||||
|
||||
inline float pow(float x, float y)
|
||||
{
|
||||
return powf(x, y);
|
||||
}
|
||||
|
||||
#endif // _MSC_VER < 1300
|
||||
|
||||
#else
|
||||
|
||||
// @todo check standard, if cmath.h will not be deprecated,
|
||||
// include cmath.h here and get rid of the redundant inlines.
|
||||
#include <cmath>
|
||||
|
||||
#ifndef LINUX
|
||||
// The Linux setup defines this in PlatformGlue.h
|
||||
inline float abs(float f)
|
||||
{
|
||||
return std::abs(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline float sqrt(float f)
|
||||
{
|
||||
return std::sqrt(f);
|
||||
}
|
||||
|
||||
inline float sin(float f)
|
||||
{
|
||||
return std::sin(f);
|
||||
}
|
||||
|
||||
inline float cos(float f)
|
||||
{
|
||||
return std::cos(f);
|
||||
}
|
||||
|
||||
inline float tan(float f)
|
||||
{
|
||||
return std::tan(f);
|
||||
}
|
||||
|
||||
inline float asin(float f)
|
||||
{
|
||||
return std::asin(f);
|
||||
}
|
||||
|
||||
inline float acos(float f)
|
||||
{
|
||||
return std::acos(f);
|
||||
}
|
||||
|
||||
inline float atan2(float y, float x)
|
||||
{
|
||||
return std::atan2(y, x);
|
||||
}
|
||||
|
||||
inline float pow(float x, float y)
|
||||
{
|
||||
return std::pow(x, y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline float convertDegreesToRadians (real degrees)
|
||||
{
|
||||
return degrees * PI / 180.0f;
|
||||
}
|
||||
|
||||
inline float convertRadiansToDegrees (real radians)
|
||||
{
|
||||
return radians * 180.0f / PI;
|
||||
}
|
||||
|
||||
inline float cot(float f)
|
||||
{
|
||||
return RECIP(tanf(f));
|
||||
}
|
||||
|
||||
inline float GaussianDistribution(float variate, float standardDeviation, float mean)
|
||||
{
|
||||
// equation from http://mathworld.wolfram.com/NormalDistribution.html
|
||||
return (1.0f / (standardDeviation * sqrt(2.0f * PI))) * pow(E, -(sqr(variate - mean) / (2.0f * sqr(standardDeviation))));
|
||||
}
|
||||
|
||||
inline float withinEpsilon(float const rhs, float const lhs, float const epsilon = 1.0e-3f)
|
||||
{
|
||||
return ((lhs - epsilon) <= rhs) && (rhs <= (lhs + epsilon));
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FormattedString.h
|
||||
// Copyright 2004 Sony Online Entertainment, Inc.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FormattedString_H
|
||||
#define INCLUDED_FormattedString_H
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
template <int bufferSize>
|
||||
class FormattedString
|
||||
{
|
||||
public:
|
||||
|
||||
FormattedString();
|
||||
|
||||
char const * sprintf(char const * format, ...);
|
||||
char const * vsprintf(char const * format, va_list const & va);
|
||||
|
||||
private:
|
||||
|
||||
char m_text[bufferSize];
|
||||
|
||||
// Disabled
|
||||
|
||||
FormattedString(FormattedString const &);
|
||||
FormattedString & operator =(FormattedString const &);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
template <int bufferSize>
|
||||
inline FormattedString<bufferSize>::FormattedString()
|
||||
{
|
||||
m_text[0] = '\0';
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <int bufferSize>
|
||||
inline char const * FormattedString<bufferSize>::sprintf(char const * const format, ...)
|
||||
{
|
||||
char const * result = NULL;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
{
|
||||
result = vsprintf(format, va);
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
template <int bufferSize>
|
||||
inline char const * FormattedString<bufferSize>::vsprintf(char const * const format, va_list const & va)
|
||||
{
|
||||
// Format the string
|
||||
|
||||
int const lastIndex = sizeof(m_text) - 1;
|
||||
int const charactersWritten = vsnprintf(m_text, lastIndex, format, va);
|
||||
|
||||
// vsnprintf returns the number of characters written, not including
|
||||
// the terminating null character, or a negative value if an output error occurs.
|
||||
// If the number of characters to write exceeds count, then count characters are
|
||||
// written and -1 is returned.
|
||||
|
||||
// Handle overflow
|
||||
|
||||
if ( (charactersWritten == lastIndex)
|
||||
|| (charactersWritten == -1))
|
||||
{
|
||||
m_text[lastIndex - 1] = '+';
|
||||
m_text[lastIndex] = '\0';
|
||||
}
|
||||
|
||||
return m_text;
|
||||
}
|
||||
|
||||
#endif // INCLUDED_FormattedString_H
|
||||
|
||||
// ======================================================================
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// GameControllerMessage.h
|
||||
// asommers 2-24-99
|
||||
//
|
||||
// copyright 1999, bootprint entertainment
|
||||
//
|
||||
// data files should be including GameControllerMessage.def
|
||||
// code files should be including GameControllerMessage.h
|
||||
|
||||
#ifndef GAMECONTROLLERMESSAGE_H
|
||||
#define GAMECONTROLLERMESSAGE_H
|
||||
|
||||
namespace GameControllerMessageFlags
|
||||
{
|
||||
const uint32 NONE = 0x00000000;
|
||||
const uint32 SEND = 0x00000001; // send should always be combined with one of the dest flags below
|
||||
const uint32 RELIABLE = 0x00000002;
|
||||
const uint32 SOURCE_REMOTE_SERVER = 0x00000004;
|
||||
const uint32 DEST_AUTH_CLIENT = 0x00000008;
|
||||
const uint32 DEST_PROXY_CLIENT = 0x00000010;
|
||||
const uint32 DEST_AUTH_SERVER = 0x00000020;
|
||||
const uint32 DEST_PROXY_SERVER = 0x00000040;
|
||||
const uint32 DEST_SERVER = 0x00000080;
|
||||
const uint32 SOURCE_REMOTE_CLIENT = 0x00000100;
|
||||
|
||||
const uint32 DEST_ALL_CLIENT = DEST_AUTH_CLIENT | DEST_PROXY_CLIENT;
|
||||
const uint32 DEST_ALL_SERVER = DEST_AUTH_SERVER | DEST_PROXY_SERVER;
|
||||
const uint32 DEST_ALL = DEST_ALL_CLIENT | DEST_ALL_SERVER;
|
||||
|
||||
const uint32 SOURCE_REMOTE = SOURCE_REMOTE_SERVER | SOURCE_REMOTE_CLIENT;
|
||||
|
||||
//@todo remove DESTINATIONS and DEST_SERVER
|
||||
const uint32 DESTINATIONS = DEST_AUTH_CLIENT |
|
||||
DEST_PROXY_CLIENT |
|
||||
DEST_AUTH_SERVER |
|
||||
DEST_PROXY_SERVER |
|
||||
DEST_SERVER;
|
||||
}
|
||||
|
||||
#include "sharedFoundation/GameControllerMessage.def"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,132 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// LabelHash.cpp
|
||||
//
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/LabelHash.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "sharedFoundation/Crc.h"
|
||||
|
||||
typedef std::map< uint32, std::string > THashToStringMap;
|
||||
|
||||
typedef THashToStringMap::value_type THashEntry;
|
||||
|
||||
typedef std::map< std::string, THashToStringMap > TDomainMap;
|
||||
|
||||
typedef TDomainMap::value_type TDomainEntry;
|
||||
|
||||
TDomainMap gs_allDomains;
|
||||
|
||||
void LabelHash::addLabel ( char const * const domain, char const * const label )
|
||||
{
|
||||
uint32 actualHash = Crc::calculate(label);
|
||||
|
||||
checkLabel(domain,label,actualHash);
|
||||
}
|
||||
|
||||
uint32 LabelHash::hashLabel ( char const * const domain, char const * const label )
|
||||
{
|
||||
uint32 actualHash = Crc::calculate(label);
|
||||
|
||||
checkLabel(domain,label,actualHash);
|
||||
|
||||
return actualHash;
|
||||
}
|
||||
|
||||
uint32 LabelHash::checkLabel( char const * const domain, char const * const label, uint32 hashValue )
|
||||
{
|
||||
// First things first - make sure the label actually hashes to the given value
|
||||
|
||||
uint32 actualHash = Crc::calculate(label);
|
||||
|
||||
FATAL(actualHash != hashValue, ("LabelHash::checkLabel - Label [%s] hashes to [%d] and not [%d]\n",label,actualHash,hashValue));
|
||||
|
||||
// ----------
|
||||
|
||||
std::string domainString(domain);
|
||||
std::string labelString(label);
|
||||
|
||||
// Find the hash-to-label map for the given domain, or
|
||||
// create a new one if there isn't one already.
|
||||
|
||||
TDomainMap::iterator domainIt = gs_allDomains.find(domainString);
|
||||
|
||||
if(domainIt == gs_allDomains.end())
|
||||
{
|
||||
// Domain not found, create entry for it containing the label
|
||||
|
||||
THashToStringMap newDomainMap;
|
||||
|
||||
newDomainMap.insert( THashEntry(hashValue,labelString) );
|
||||
|
||||
gs_allDomains.insert( TDomainEntry(domainString,newDomainMap) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Domain found, check for existing hash value
|
||||
|
||||
THashToStringMap & domainLabels = (*domainIt).second;
|
||||
|
||||
THashToStringMap::iterator labelIt = domainLabels.find(hashValue);
|
||||
|
||||
if(labelIt == domainLabels.end())
|
||||
{
|
||||
// Hash value not found, add it to the domain
|
||||
|
||||
domainLabels.insert( THashEntry(hashValue,labelString) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hash value found, fatal if the string mapped to it doesn't match
|
||||
// the given string
|
||||
|
||||
std::string & currentLabel = (*labelIt).second;
|
||||
|
||||
FATAL( currentLabel != labelString, ("LabelHash::checkLabel - Found a hash collision for domain [%s], label [%s] - two labels hashed to the same value\n",domain,label));
|
||||
}
|
||||
}
|
||||
|
||||
// All is good, hash is OK.
|
||||
|
||||
return hashValue;
|
||||
};
|
||||
|
||||
|
||||
const char * LabelHash::findLabel( char const * const domain, uint32 hashValue )
|
||||
{
|
||||
std::string domainString(domain);
|
||||
|
||||
TDomainMap::iterator domainIt = gs_allDomains.find(domainString);
|
||||
|
||||
if(domainIt == gs_allDomains.end())
|
||||
{
|
||||
// Domain not found
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------
|
||||
// Domain found, check for existing hash value
|
||||
|
||||
THashToStringMap & domainLabels = (*domainIt).second;
|
||||
|
||||
THashToStringMap::iterator hashIt = domainLabels.find(hashValue);
|
||||
|
||||
if(hashIt != domainLabels.end())
|
||||
{
|
||||
return (*hashIt).second.c_str();
|
||||
}
|
||||
|
||||
// ----------
|
||||
// String not found
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// LabelHash.h
|
||||
//
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_LabelHash_H
|
||||
#define INCLUDED_LabelHash_H
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
class LabelHash
|
||||
{
|
||||
public:
|
||||
|
||||
typedef uint32 Id;
|
||||
|
||||
static void addLabel ( char const * const domain, char const * const label );
|
||||
|
||||
static Id hashLabel ( char const * const domain, char const * const label );
|
||||
|
||||
static Id checkLabel ( char const * const domain, char const * const label, Id hashValue );
|
||||
|
||||
static const char * findLabel ( char const * const domain, Id hashValue );
|
||||
};
|
||||
|
||||
// ----------
|
||||
|
||||
//#define LABEL_HASH(domain,label) (LabelHash::hashLabel(#domain,#label))
|
||||
|
||||
// ----------
|
||||
|
||||
#if DEBUG_LEVEL == DEBUG_LEVEL_DEBUG
|
||||
|
||||
// the ##u is so that the compiler interprets the value as an unsigned integer constant
|
||||
|
||||
#define LABEL_HASH(domain,label,value) (LabelHash::checkLabel(#domain,#label,value##u))
|
||||
|
||||
#else
|
||||
|
||||
#define LABEL_HASH(domain,label,value) (value##u)
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef INCLUDED_LabelHash_H
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// LessPointerComparator.h
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef LESS_POINTER_COMPARATOR_H
|
||||
#define LESS_POINTER_COMPARATOR_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class LessPointerComparator
|
||||
{
|
||||
public:
|
||||
template <typename PointerType>
|
||||
bool operator ()(PointerType lhs, PointerType rhs) const
|
||||
{
|
||||
return *lhs < *rhs;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
template <typename T> class LessPointerComparatorStatic
|
||||
{
|
||||
public:
|
||||
static bool compare(T * a, T * b)
|
||||
{
|
||||
return *a < *b;
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MacroFoundation.h
|
||||
// copyright (c) 1998 Bootprint Entertainment
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_MacroFoundation_H
|
||||
#define INCLUDED_MacroFoundation_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// No-operation
|
||||
#define NOP (static_cast<void>(0)) //lint !e1923 //could become const variable
|
||||
|
||||
// To prevent "Unreference" compiler warning
|
||||
#define UNREF(a) (static_cast<void>(a))
|
||||
|
||||
// To prevent "Ignoring return value" lint warnings
|
||||
#define IGNORE_RETURN(a) (static_cast<void>(a))
|
||||
|
||||
// int version of the sizeof operator
|
||||
#define isizeof(a) static_cast<int>(sizeof(a))
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,339 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Md5.cpp
|
||||
//
|
||||
// Portions copyright 2003 Sony Online Entertainment
|
||||
// Portions derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
|
||||
// Portions derived from Dan Gorman's implementation
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Md5.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
Md5::Value::Value()
|
||||
{
|
||||
memset(m_data, 0, sizeof(m_data));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Md5::Value::Value(Value const &rhs)
|
||||
{
|
||||
memcpy(m_data, rhs.m_data, sizeof(m_data));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Md5::Value::operator ==(Value const &rhs) const
|
||||
{
|
||||
return memcmp(m_data, rhs.m_data, sizeof(m_data)) == 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool Md5::Value::operator !=(Value const &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::Value::format(char *buffer, int bufferLength) const
|
||||
{
|
||||
//not referenced in release build
|
||||
UNREF(bufferLength);
|
||||
DEBUG_FATAL(bufferLength < 33, ("PB: buffer must be at least 33 characters"));
|
||||
sprintf(buffer, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", m_data[0], m_data[1], m_data[2], m_data[3], m_data[4], m_data[5], m_data[6], m_data[7], m_data[8], m_data[9], m_data[10], m_data[11], m_data[12], m_data[13], m_data[14], m_data[15]);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
Md5::Value Md5::calculate(const char *string)
|
||||
{
|
||||
return calculate(string, strlen(string));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Md5::Value Md5::calculate(void const *data, int length)
|
||||
{
|
||||
Md5 md5;
|
||||
md5.update(data, length);
|
||||
md5.finish();
|
||||
return md5.getValue();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
Md5::Md5()
|
||||
:
|
||||
m_bufferedBytes(0),
|
||||
m_totalLength(0),
|
||||
m_finished(false)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::reset()
|
||||
{
|
||||
m_data[0] = 0x67452301;
|
||||
m_data[1] = 0xefcdab89;
|
||||
m_data[2] = 0x98badcfe;
|
||||
m_data[3] = 0x10325476;
|
||||
m_bufferedBytes = 0;
|
||||
m_totalLength = 0;
|
||||
m_finished = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::update(void const *data, int length)
|
||||
{
|
||||
m_totalLength += length;
|
||||
|
||||
byte const * byteData = reinterpret_cast<byte const *>(data);
|
||||
while (length > 0)
|
||||
{
|
||||
// if there's no bytes pending from last time and we have a full block incoming transform it directly to avoid the copy
|
||||
if (m_bufferedBytes == 0 && length >= BUFFER_SIZE)
|
||||
{
|
||||
transformBlock(byteData);
|
||||
byteData += BUFFER_SIZE;
|
||||
length -= BUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// figure out how many bytes to copy into the temp buffer
|
||||
int bytesToCopy = BUFFER_SIZE - m_bufferedBytes;
|
||||
if (length < bytesToCopy)
|
||||
bytesToCopy = length;
|
||||
|
||||
// copy the data into the temp buffer
|
||||
memmove(m_buffer + m_bufferedBytes, byteData, bytesToCopy);
|
||||
m_bufferedBytes += bytesToCopy;
|
||||
byteData += bytesToCopy;
|
||||
length -= bytesToCopy;
|
||||
|
||||
// if we've managed to fill the temp buffer, transform it
|
||||
if (m_bufferedBytes == BUFFER_SIZE)
|
||||
{
|
||||
transformBlock(m_buffer);
|
||||
m_bufferedBytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::wordsToBytes(const uint32* words, size_t wordCnt, uint8* bytes)
|
||||
{
|
||||
const int bytesPerWord = sizeof(*words)/sizeof(*bytes);
|
||||
while ((wordCnt--) > 0)
|
||||
{
|
||||
uint32 wd = *(words++);
|
||||
int cnt = bytesPerWord;
|
||||
while (cnt-- > 0)
|
||||
{
|
||||
*(bytes++) = static_cast<uint8>(wd & 0x0ff);
|
||||
wd >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::bytesToWords(const uint8* bytes, size_t byteCnt, uint32* words)
|
||||
{
|
||||
const int bytesPerWord = sizeof(*words)/sizeof(*bytes);
|
||||
size_t wdcnt = byteCnt/bytesPerWord;
|
||||
while (wdcnt-- > 0)
|
||||
{
|
||||
uint32 wd = 0;
|
||||
int cnt = bytesPerWord;
|
||||
int shft = 0;
|
||||
while (cnt-- > 0)
|
||||
{
|
||||
wd |= static_cast<uint32>(*(bytes++) & 0x0ff) << shft;
|
||||
shft += 8;
|
||||
}
|
||||
*(words++) = wd;
|
||||
byteCnt -= bytesPerWord;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline uint32 Md5::rotate_left(uint32 ival, uint32 shft)
|
||||
{
|
||||
return ((ival << shft) | (ival >> (32-shft)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline uint32 Md5::round1(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1)
|
||||
{
|
||||
i += ((j & k) | (~j & l)) + i1 + k1;
|
||||
return rotate_left(i, j1) + j;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline uint32 Md5::round2(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1)
|
||||
{
|
||||
i += ((j & l) | (k & ~l)) + i1 + k1;
|
||||
return rotate_left(i, j1) + j;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline uint32 Md5::round3(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1)
|
||||
{
|
||||
i += (j ^ k ^ l) + i1 + k1;
|
||||
return rotate_left(i, j1) + j;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline uint32 Md5::round4(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1)
|
||||
{
|
||||
i += (k ^ (j | ~l)) + i1 + k1;
|
||||
return rotate_left(i, j1) + j;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::transformBlock(void const * data)
|
||||
{
|
||||
// pack the bytes into 32-bit little endian words
|
||||
uint32 work[64 / 4];
|
||||
bytesToWords(reinterpret_cast<byte const *>(data), 64, work);
|
||||
//uint32 const * work = reinterpret_cast<uint32 const *>(data);
|
||||
|
||||
uint32 j = m_data[0];
|
||||
uint32 k = m_data[1];
|
||||
uint32 l = m_data[2];
|
||||
uint32 m = m_data[3];
|
||||
|
||||
j = round1(j, k, l, m, work[0], 7, 0xd76aa478);
|
||||
m = round1(m, j, k, l, work[1], 12, 0xe8c7b756);
|
||||
l = round1(l, m, j, k, work[2], 17, 0x242070db);
|
||||
k = round1(k, l, m, j, work[3], 22, 0xc1bdceee);
|
||||
j = round1(j, k, l, m, work[4], 7, 0xf57c0faf);
|
||||
m = round1(m, j, k, l, work[5], 12, 0x4787c62a);
|
||||
l = round1(l, m, j, k, work[6], 17, 0xa8304613);
|
||||
k = round1(k, l, m, j, work[7], 22, 0xfd469501);
|
||||
j = round1(j, k, l, m, work[8], 7, 0x698098d8);
|
||||
m = round1(m, j, k, l, work[9], 12, 0x8b44f7af);
|
||||
l = round1(l, m, j, k, work[10], 17, 0xffff5bb1);
|
||||
k = round1(k, l, m, j, work[11], 22, 0x895cd7be);
|
||||
j = round1(j, k, l, m, work[12], 7, 0x6b901122);
|
||||
m = round1(m, j, k, l, work[13], 12, 0xfd987193);
|
||||
l = round1(l, m, j, k, work[14], 17, 0xa679438e);
|
||||
k = round1(k, l, m, j, work[15], 22, 0x49b40821);
|
||||
|
||||
j = round2(j, k, l, m, work[1], 5, 0xf61e2562);
|
||||
m = round2(m, j, k, l, work[6], 9, 0xc040b340);
|
||||
l = round2(l, m, j, k, work[11], 14, 0x265e5a51);
|
||||
k = round2(k, l, m, j, work[0], 20, 0xe9b6c7aa);
|
||||
j = round2(j, k, l, m, work[5], 5, 0xd62f105d);
|
||||
m = round2(m, j, k, l, work[10], 9, 0x02441453);
|
||||
l = round2(l, m, j, k, work[15], 14, 0xd8a1e681);
|
||||
k = round2(k, l, m, j, work[4], 20, 0xe7d3fbc8);
|
||||
j = round2(j, k, l, m, work[9], 5, 0x21e1cde6);
|
||||
m = round2(m, j, k, l, work[14], 9, 0xc33707d6);
|
||||
l = round2(l, m, j, k, work[3], 14, 0xf4d50d87);
|
||||
k = round2(k, l, m, j, work[8], 20, 0x455a14ed);
|
||||
j = round2(j, k, l, m, work[13], 5, 0xa9e3e905);
|
||||
m = round2(m, j, k, l, work[2], 9, 0xfcefa3f8);
|
||||
l = round2(l, m, j, k, work[7], 14, 0x676f02d9);
|
||||
k = round2(k, l, m, j, work[12], 20, 0x8d2a4c8a);
|
||||
|
||||
j = round3(j, k, l, m, work[5], 4, 0xfffa3942);
|
||||
m = round3(m, j, k, l, work[8], 11, 0x8771f681);
|
||||
l = round3(l, m, j, k, work[11], 16, 0x6d9d6122);
|
||||
k = round3(k, l, m, j, work[14], 23, 0xfde5380c);
|
||||
j = round3(j, k, l, m, work[1], 4, 0xa4beea44);
|
||||
m = round3(m, j, k, l, work[4], 11, 0x4bdecfa9);
|
||||
l = round3(l, m, j, k, work[7], 16, 0xf6bb4b60);
|
||||
k = round3(k, l, m, j, work[10], 23, 0xbebfbc70);
|
||||
j = round3(j, k, l, m, work[13], 4, 0x289b7ec6);
|
||||
m = round3(m, j, k, l, work[0], 11, 0xeaa127fa);
|
||||
l = round3(l, m, j, k, work[3], 16, 0xd4ef3085);
|
||||
k = round3(k, l, m, j, work[6], 23, 0x04881d05);
|
||||
j = round3(j, k, l, m, work[9], 4, 0xd9d4d039);
|
||||
m = round3(m, j, k, l, work[12], 11, 0xe6db99e5);
|
||||
l = round3(l, m, j, k, work[15], 16, 0x1fa27cf8);
|
||||
k = round3(k, l, m, j, work[2], 23, 0xc4ac5665);
|
||||
|
||||
j = round4(j, k, l, m, work[0], 6, 0xf4292244);
|
||||
m = round4(m, j, k, l, work[7], 10, 0x432aff97);
|
||||
l = round4(l, m, j, k, work[14], 15, 0xab9423a7);
|
||||
k = round4(k, l, m, j, work[5], 21, 0xfc93a039);
|
||||
j = round4(j, k, l, m, work[12], 6, 0x655b59c3);
|
||||
m = round4(m, j, k, l, work[3], 10, 0x8f0ccc92);
|
||||
l = round4(l, m, j, k, work[10], 15, 0xffeff47d);
|
||||
k = round4(k, l, m, j, work[1], 21, 0x85845dd1);
|
||||
j = round4(j, k, l, m, work[8], 6, 0x6fa87e4f);
|
||||
m = round4(m, j, k, l, work[15], 10, 0xfe2ce6e0);
|
||||
l = round4(l, m, j, k, work[6], 15, 0xa3014314);
|
||||
k = round4(k, l, m, j, work[13], 21, 0x4e0811a1);
|
||||
j = round4(j, k, l, m, work[4], 6, 0xf7537e82);
|
||||
m = round4(m, j, k, l, work[11], 10, 0xbd3af235);
|
||||
l = round4(l, m, j, k, work[2], 15, 0x2ad7d2bb);
|
||||
k = round4(k, l, m, j, work[9], 21, 0xeb86d391);
|
||||
|
||||
m_data[0] += j;
|
||||
m_data[1] += k;
|
||||
m_data[2] += l;
|
||||
m_data[3] += m;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Md5::finish()
|
||||
{
|
||||
DEBUG_FATAL(m_finished, ("PB: MD5 already finished"));
|
||||
|
||||
uint64 messageLengthInBits = m_totalLength * 8;
|
||||
|
||||
// we always have to append a trailing bit
|
||||
{
|
||||
byte append = 0x80;
|
||||
update(&append, 1);
|
||||
}
|
||||
|
||||
// how much to pad to existing bytes to come out to an even 64 byte multiple, yet leave room at the end for the count.
|
||||
while (m_bufferedBytes != (BUFFER_SIZE - 8))
|
||||
{
|
||||
byte append = 0x00;
|
||||
update(&append, 1);
|
||||
}
|
||||
|
||||
// append the length of the source message in bits
|
||||
uint8 countAsBytes[8];
|
||||
wordsToBytes(reinterpret_cast<const uint32*>(&(messageLengthInBits)), 2, countAsBytes);
|
||||
update(countAsBytes, 8);
|
||||
|
||||
m_finished = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Md5::Value Md5::getValue() const
|
||||
{
|
||||
DEBUG_FATAL(!m_finished, ("PB: did not finish MD5 before calling getValue"));
|
||||
|
||||
Value v;
|
||||
wordsToBytes(m_data, 4, v.m_data);
|
||||
return v;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,99 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Md5.h
|
||||
//
|
||||
// copyright 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Md5_H
|
||||
#define INCLUDED_Md5_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Md5
|
||||
{
|
||||
public:
|
||||
|
||||
class Value
|
||||
{
|
||||
friend class Md5;
|
||||
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
cms_dataSize = 16
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Value();
|
||||
Value(Value const &rhs);
|
||||
|
||||
bool operator ==(Value const &rhs) const;
|
||||
bool operator !=(Value const &rhs) const;
|
||||
void format(char *buffer, int bufferLength) const;
|
||||
|
||||
void *getData();
|
||||
|
||||
private:
|
||||
|
||||
uint8 m_data[cms_dataSize];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static Value calculate(const char *string);
|
||||
static Value calculate(const void *data, int len);
|
||||
|
||||
public:
|
||||
|
||||
Md5();
|
||||
|
||||
void reset();
|
||||
void update(void const *data, int len);
|
||||
void finish();
|
||||
Value getValue() const;
|
||||
|
||||
private:
|
||||
|
||||
static void wordsToBytes(const uint32* words, size_t wordCnt, uint8* bytes);
|
||||
static void bytesToWords(const uint8* bytes, size_t byteCnt, uint32* words);
|
||||
static uint32 rotate_left(uint32 ival, uint32 shft);
|
||||
static uint32 round1(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1);
|
||||
static uint32 round2(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1);
|
||||
static uint32 round3(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1);
|
||||
static uint32 round4(uint32 i, uint32 j, uint32 k, uint32 l, uint32 i1, uint32 j1, uint32 k1);
|
||||
|
||||
void transformBlock(void const *data);
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
BUFFER_SIZE = 64
|
||||
};
|
||||
|
||||
uint32 m_data[4];
|
||||
byte m_buffer[BUFFER_SIZE];
|
||||
int m_bufferedBytes;
|
||||
int m_totalLength;
|
||||
bool m_finished;
|
||||
|
||||
public:
|
||||
|
||||
Md5(Md5 const &);
|
||||
Md5 & operator =(Md5 const &);
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline void * Md5::Value::getData()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,636 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MemoryBlockManager.cpp
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
// copyright 2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/MemoryBlockManager.h"
|
||||
|
||||
#include "sharedDebug/DebugFlags.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/ConfigSharedFoundation.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#define PASS_THROUGH_TO_GLOBAL_MEMORY_MANAGER 0
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class MemoryBlockManager::Allocator
|
||||
{
|
||||
public:
|
||||
|
||||
Allocator(int elementSize);
|
||||
Allocator(int elementSize, int elementsPerBlock, int minimumBlocks, int maximumNumberOfBlocks);
|
||||
~Allocator();
|
||||
|
||||
int getElementSize();
|
||||
|
||||
void fetch();
|
||||
bool release();
|
||||
int getReferenceCount();
|
||||
|
||||
bool isFull() const;
|
||||
int getNumberOfAllocatedElements();
|
||||
void *allocate();
|
||||
void free(void *pointer);
|
||||
|
||||
#ifdef _DEBUG
|
||||
void debugDump () const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
struct Block
|
||||
{
|
||||
Block *next;
|
||||
byte *data;
|
||||
};
|
||||
|
||||
struct Element
|
||||
{
|
||||
Element *next;
|
||||
};
|
||||
|
||||
void *realAlloc();
|
||||
void realFree(void *pointer);
|
||||
|
||||
void placeOnFreeList(Element *element);
|
||||
void allocateNewBlock();
|
||||
|
||||
private:
|
||||
|
||||
Allocator();
|
||||
Allocator(Allocator const &);
|
||||
Allocator &operator =(Allocator const &);
|
||||
|
||||
private:
|
||||
|
||||
int m_referenceCount;
|
||||
|
||||
// first block on the allocated block list
|
||||
Block *m_firstBlock;
|
||||
|
||||
// first free element
|
||||
Element *m_firstFreeElement;
|
||||
|
||||
// size of each element
|
||||
int m_elementSize;
|
||||
|
||||
// number of elements per block
|
||||
int m_elementsPerBlock;
|
||||
|
||||
// current number of blocks in existance
|
||||
int m_currentNumberOfBlocks;
|
||||
|
||||
// current number of blocks that are allowed to exist, 0 for unliminted
|
||||
int m_maximumNumberOfBlocks;
|
||||
|
||||
// number of outstanding allocations
|
||||
int m_numberOfAllocatedElements;
|
||||
|
||||
#ifdef _DEBUG
|
||||
int m_lifetimeAllocatedElements;
|
||||
#endif
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace MemoryBlockManagerNamespace
|
||||
{
|
||||
bool ms_debugDumpOnRemove = false;
|
||||
bool ms_forceAllNonShared = false;
|
||||
#ifdef _DEBUG
|
||||
bool ms_debugReport = false;
|
||||
int ms_debugNumberOfAllocations = 0;
|
||||
int ms_debugNumberOfBytes = 0;
|
||||
bool ms_debugDumpAllNextFrame = false;
|
||||
typedef std::vector<MemoryBlockManager*> MemoryBlockManagerList;
|
||||
MemoryBlockManagerList ms_memoryBlockManagerList;
|
||||
#endif
|
||||
|
||||
typedef std::map<int, MemoryBlockManager::Allocator *> Allocators;
|
||||
Allocators ms_allocators;
|
||||
|
||||
Mutex ms_globalCriticalSection;
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool m_usingMemoryBlockManager = false;
|
||||
#endif
|
||||
|
||||
void remove();
|
||||
#ifdef _DEBUG
|
||||
void debugReport();
|
||||
void debugDumpAll ();
|
||||
#endif
|
||||
}
|
||||
|
||||
using namespace MemoryBlockManagerNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
MemoryBlockManager::Allocator::Allocator(const int elementSize)
|
||||
:
|
||||
m_referenceCount(0),
|
||||
m_firstBlock(NULL),
|
||||
m_firstFreeElement(NULL),
|
||||
m_elementSize(elementSize),
|
||||
m_elementsPerBlock(64),
|
||||
m_currentNumberOfBlocks(0),
|
||||
m_maximumNumberOfBlocks(0),
|
||||
m_numberOfAllocatedElements(0)
|
||||
#ifdef _DEBUG
|
||||
,
|
||||
m_lifetimeAllocatedElements(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
MemoryBlockManager::Allocator::Allocator(int elementSize, int elementsPerBlock, int minimumBlocks, int maximumNumberOfBlocks)
|
||||
:
|
||||
m_referenceCount(0),
|
||||
m_firstBlock(NULL),
|
||||
m_firstFreeElement(NULL),
|
||||
m_elementSize(elementSize),
|
||||
m_elementsPerBlock(elementsPerBlock),
|
||||
m_currentNumberOfBlocks(0),
|
||||
m_maximumNumberOfBlocks(maximumNumberOfBlocks),
|
||||
m_numberOfAllocatedElements(0)
|
||||
#ifdef _DEBUG
|
||||
,
|
||||
m_lifetimeAllocatedElements(0)
|
||||
#endif
|
||||
{
|
||||
for (int i = 0; i < minimumBlocks; ++i)
|
||||
allocateNewBlock();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
MemoryBlockManager::Allocator::~Allocator()
|
||||
{
|
||||
if (ExitChain::isFataling())
|
||||
return;
|
||||
|
||||
while (m_firstBlock)
|
||||
{
|
||||
Block * block = m_firstBlock;
|
||||
m_firstBlock = m_firstBlock->next;
|
||||
delete [] block->data;
|
||||
delete block;
|
||||
}
|
||||
|
||||
m_firstBlock = NULL;
|
||||
m_firstFreeElement = NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MemoryBlockManager::Allocator::fetch()
|
||||
{
|
||||
++m_referenceCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool MemoryBlockManager::Allocator::release()
|
||||
{
|
||||
if (--m_referenceCount <= 0)
|
||||
{
|
||||
DEBUG_FATAL(m_referenceCount < 0, ("reference count went negative"));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
inline int MemoryBlockManager::Allocator::getElementSize()
|
||||
{
|
||||
return m_elementSize;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int MemoryBlockManager::Allocator::getReferenceCount()
|
||||
{
|
||||
return m_referenceCount;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool MemoryBlockManager::Allocator::isFull() const
|
||||
{
|
||||
return m_maximumNumberOfBlocks && m_numberOfAllocatedElements >= m_elementsPerBlock * m_maximumNumberOfBlocks;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int MemoryBlockManager::Allocator::getNumberOfAllocatedElements()
|
||||
{
|
||||
return m_numberOfAllocatedElements;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *MemoryBlockManager::Allocator::allocate()
|
||||
{
|
||||
void *result = 0;
|
||||
|
||||
// check if there are any free elements
|
||||
if (!m_firstFreeElement)
|
||||
allocateNewBlock();
|
||||
|
||||
result = m_firstFreeElement;
|
||||
m_firstFreeElement = m_firstFreeElement->next;
|
||||
++m_numberOfAllocatedElements;
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_lifetimeAllocatedElements += 1;
|
||||
ms_debugNumberOfAllocations += 1;
|
||||
ms_debugNumberOfBytes += getElementSize();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MemoryBlockManager::Allocator::free(void *pointer)
|
||||
{
|
||||
DEBUG_FATAL(m_numberOfAllocatedElements <= 0, ("freeing an element when already empty"));
|
||||
Element *element = reinterpret_cast<Element *>(pointer);
|
||||
placeOnFreeList(element);
|
||||
--m_numberOfAllocatedElements;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Places an element on the free element list
|
||||
*/
|
||||
|
||||
void MemoryBlockManager::Allocator::placeOnFreeList(Element *element)
|
||||
{
|
||||
NOT_NULL(element);
|
||||
element->next = m_firstFreeElement;
|
||||
m_firstFreeElement = element;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get a new block and put its elements on the free list.
|
||||
*
|
||||
* Will not allocate a new block if the maximum number of blocks has already
|
||||
* been reached.
|
||||
*/
|
||||
|
||||
void MemoryBlockManager::Allocator::allocateNewBlock()
|
||||
{
|
||||
// allocate a new block
|
||||
Block *block = new Block;
|
||||
block->data = new byte[static_cast<size_t>(m_elementSize * m_elementsPerBlock)];
|
||||
|
||||
// put the block on the block list
|
||||
block->next = m_firstBlock;
|
||||
m_firstBlock = block;
|
||||
|
||||
// put all the new block elements on the free list
|
||||
{
|
||||
int i;
|
||||
byte *data;
|
||||
|
||||
for (i = m_elementsPerBlock, data = block->data; i; --i, data += m_elementSize)
|
||||
placeOnFreeList(reinterpret_cast<Element *>(data)); //lint !e826 // suspicious pointer conversion (area too small)
|
||||
}
|
||||
|
||||
// count the new block
|
||||
++m_currentNumberOfBlocks;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
void MemoryBlockManager::Allocator::debugDump() const
|
||||
{
|
||||
const int currentUsageInKilobytes = m_numberOfAllocatedElements * m_elementSize / 1024;
|
||||
const int totalUsageInKilobytes = (m_currentNumberOfBlocks * m_elementsPerBlock * m_elementSize) / 1024;
|
||||
const int percent = totalUsageInKilobytes ? ((currentUsageInKilobytes * 100) / totalUsageInKilobytes) : 0;
|
||||
DEBUG_REPORT_LOG(true, ("MBMA elementSize=%d elements=%d elementsPerBlock=%d blocks=%d mem=%dk full=%d%%\n", m_elementSize, m_numberOfAllocatedElements, m_elementsPerBlock, m_currentNumberOfBlocks, totalUsageInKilobytes, percent));
|
||||
}
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void MemoryBlockManager::install(bool debugDumpOnRemove)
|
||||
{
|
||||
ms_debugDumpOnRemove = debugDumpOnRemove;
|
||||
|
||||
#if PASS_THROUGH_TO_GLOBAL_MEMORY_MANAGER
|
||||
DEBUG_WARNING(true, ("MemoryBlockManager enabled PASS_THROUGH_TO_GLOBAL_MEMORY_MANAGER"));
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
m_usingMemoryBlockManager = ConfigSharedFoundation::getUseMemoryBlockManager();
|
||||
#endif
|
||||
#if PASS_THROUGH_TO_GLOBAL_MEMORY_MANAGER
|
||||
m_usingMemoryBlockManager = false;
|
||||
#endif
|
||||
|
||||
DebugFlags::registerFlag(ms_forceAllNonShared, "SharedFoundation", "memoryBlockManagerForceAllNonShared");
|
||||
REPORT_LOG(ms_forceAllNonShared, ("MemoryBlockManager enabled memoryBlockManagerForceAllNonShared\n"));
|
||||
|
||||
#ifdef _DEBUG
|
||||
DebugFlags::registerFlag(ms_debugReport, "SharedFoundation", "reportMemoryBlockManager", debugReport);
|
||||
DebugFlags::registerFlag(ms_debugDumpAllNextFrame, "SharedFoundation", "memoryBlockManagerDebugDumpAllNextFrame", debugDumpAll);
|
||||
#endif
|
||||
|
||||
ExitChain::add(MemoryBlockManagerNamespace::remove, "MemoryBlockManager::remove");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MemoryBlockManagerNamespace::remove()
|
||||
{
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
Allocators::iterator iEnd = ms_allocators.end();
|
||||
for (Allocators::iterator i = ms_allocators.begin(); i != iEnd; ++i)
|
||||
{
|
||||
DEBUG_WARNING(true, ("Unfreed MBM %d=size %d=ref %d=items", i->second->getElementSize(), i->second->getReferenceCount(), i->second->getNumberOfAllocatedElements()));
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (ms_debugDumpOnRemove)
|
||||
{
|
||||
debugDumpAll();
|
||||
}
|
||||
#endif
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
void MemoryBlockManagerNamespace::debugReport()
|
||||
{
|
||||
ms_globalCriticalSection.enter();
|
||||
int const numberOfAllocations = ms_debugNumberOfAllocations;
|
||||
ms_debugNumberOfAllocations = 0;
|
||||
int const numberOfBytes = ms_debugNumberOfBytes;
|
||||
ms_debugNumberOfBytes = 0;
|
||||
ms_globalCriticalSection.leave();
|
||||
|
||||
DEBUG_REPORT_PRINT(true, ("mbm %d=alloc %d=bytes\n", numberOfAllocations, numberOfBytes));
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
void MemoryBlockManagerNamespace::debugDumpAll ()
|
||||
{
|
||||
{
|
||||
// dump the memory block managers and their private allocators
|
||||
uint i;
|
||||
for (i = 0; i < ms_memoryBlockManagerList.size (); ++i)
|
||||
ms_memoryBlockManagerList [i]->debugDump ();
|
||||
}
|
||||
|
||||
{
|
||||
// dump the shared allocators
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
Allocators::iterator iEnd = ms_allocators.end();
|
||||
for (Allocators::iterator i = ms_allocators.begin(); i != iEnd; ++i)
|
||||
i->second->debugDump();
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
}
|
||||
|
||||
ms_debugDumpAllNextFrame = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
MemoryBlockManager::MemoryBlockManager(char const * name, bool shared, int elementSize, int elementsPerBlock, int minimumNumberOfBlocks, int maximumNumberOfBlocks)
|
||||
: m_name(name),
|
||||
m_shared(shared),
|
||||
m_currentNumberOfElements(0),
|
||||
m_allocator(NULL)
|
||||
{
|
||||
//-- Handle config option where we force all MemoryBlockManagers to be non-shared.
|
||||
if (shared && ms_forceAllNonShared)
|
||||
{
|
||||
m_shared = false;
|
||||
shared = false;
|
||||
|
||||
if (elementsPerBlock <= 0)
|
||||
{
|
||||
//-- Adjust elements per block: caller specified as 0 because it thought it was going to be shared.
|
||||
elementsPerBlock = 100;
|
||||
}
|
||||
}
|
||||
|
||||
if (elementSize < isizeof(void*))
|
||||
elementSize = isizeof(void*);
|
||||
|
||||
if (m_shared)
|
||||
{
|
||||
DEBUG_FATAL(elementsPerBlock, ("elementsPerBlock must be 0 if shared"));
|
||||
DEBUG_FATAL(minimumNumberOfBlocks, ("minimumNumberOfBlocks must be 0 if shared"));
|
||||
DEBUG_FATAL(maximumNumberOfBlocks, ("maximumNumberOfBlocks must be 0 if shared"));
|
||||
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
Allocators::iterator i = ms_allocators.find(elementSize);
|
||||
if (i == ms_allocators.end())
|
||||
{
|
||||
// construct it and put it on the map
|
||||
i = ms_allocators.insert(Allocators::value_type(elementSize, new Allocator(elementSize))).first;
|
||||
}
|
||||
|
||||
m_allocator = i->second;
|
||||
m_allocator->fetch();
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
}
|
||||
else
|
||||
{
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
DEBUG_FATAL(elementsPerBlock == 0, ("elementsPerBlock may not be 0 if shared"));
|
||||
m_allocator = new Allocator(elementSize, elementsPerBlock, minimumNumberOfBlocks, maximumNumberOfBlocks);
|
||||
m_allocator->fetch();
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
ms_memoryBlockManagerList.push_back (this);
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
MemoryBlockManager::~MemoryBlockManager()
|
||||
{
|
||||
if (ExitChain::isFataling())
|
||||
return;
|
||||
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
MemoryBlockManagerList::iterator iter = std::find (ms_memoryBlockManagerList.begin (), ms_memoryBlockManagerList.end (), this);
|
||||
if (iter != ms_memoryBlockManagerList.end ())
|
||||
ms_memoryBlockManagerList.erase (iter);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_currentNumberOfElements)
|
||||
{
|
||||
DEBUG_WARNING(!ConfigSharedFoundation::getDemoMode(), ("MemoryBlockManager::~ %d elements still allocated in %s", m_currentNumberOfElements, m_name));
|
||||
ms_globalCriticalSection.leave();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_allocator->release())
|
||||
{
|
||||
if (m_shared)
|
||||
{
|
||||
Allocators::iterator i = ms_allocators.find(getElementSize());
|
||||
DEBUG_FATAL(i == ms_allocators.end(), ("Allocator not found"));
|
||||
DEBUG_FATAL(i->second != m_allocator, ("wrong allocator"));
|
||||
ms_allocators.erase(i);
|
||||
}
|
||||
|
||||
delete m_allocator;
|
||||
}
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
|
||||
m_allocator = 0;
|
||||
m_name = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
void MemoryBlockManager::debugDump() const
|
||||
{
|
||||
DEBUG_REPORT_LOG(true, ("MBM %s: size=%d elements=%d\n", m_name ? m_name : "<unnamed>", m_allocator->getElementSize(), m_currentNumberOfElements));
|
||||
if (!m_shared)
|
||||
m_allocator->debugDump();
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int MemoryBlockManager::getElementSize() const
|
||||
{
|
||||
return m_allocator->getElementSize();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
int MemoryBlockManager::getElementCount() const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(!m_usingMemoryBlockManager)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
ms_globalCriticalSection.enter();
|
||||
int const result = m_currentNumberOfElements;
|
||||
ms_globalCriticalSection.leave();
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
bool MemoryBlockManager::isFull() const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(!m_usingMemoryBlockManager)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
ms_globalCriticalSection.enter();
|
||||
const bool result = m_allocator->isFull();
|
||||
ms_globalCriticalSection.leave();
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void *MemoryBlockManager::allocate(bool returnNullOnFailure)
|
||||
{
|
||||
UNREF(returnNullOnFailure);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if(!m_usingMemoryBlockManager)
|
||||
{
|
||||
return operator new(getElementSize());
|
||||
}
|
||||
#endif
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
if (m_allocator->isFull())
|
||||
{
|
||||
ms_globalCriticalSection.leave();
|
||||
DEBUG_FATAL(!returnNullOnFailure, ("MBM %s is full %d", m_name, m_currentNumberOfElements));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
++m_currentNumberOfElements;
|
||||
void * result = m_allocator->allocate();
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MemoryBlockManager::free(void *pointer)
|
||||
{
|
||||
if (pointer)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(!m_usingMemoryBlockManager)
|
||||
{
|
||||
operator delete(pointer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ms_globalCriticalSection.enter();
|
||||
|
||||
if (--m_currentNumberOfElements < 0)
|
||||
DEBUG_FATAL(true, ("MBM %s number of allocated elements went negative", m_name));
|
||||
m_allocator->free(pointer);
|
||||
|
||||
ms_globalCriticalSection.leave();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,69 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MemoryBlockManager.h
|
||||
//
|
||||
// Portions copyright 1998 Bootprint Entertainment
|
||||
// Portions copyright 2000-2002 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_MemoryBlockManager_H
|
||||
#define INCLUDED_MemoryBlockManager_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class MemoryBlockManager
|
||||
{
|
||||
public:
|
||||
|
||||
static void install(bool debugDumpOnRemove);
|
||||
|
||||
public:
|
||||
|
||||
DLLEXPORT MemoryBlockManager(char const * name, bool shared, int elementSize, int elementsPerBlock, int minimumNumberOfBlocks, int maximumNumberOfBlocks);
|
||||
DLLEXPORT ~MemoryBlockManager();
|
||||
|
||||
const char * getName() const;
|
||||
|
||||
bool isFull() const;
|
||||
DLLEXPORT int getElementSize() const;
|
||||
int getElementCount() const;
|
||||
|
||||
DLLEXPORT void * allocate(bool returnNullOnFailure=false);
|
||||
DLLEXPORT void free(void * pointer);
|
||||
|
||||
public:
|
||||
|
||||
#ifdef _DEBUG
|
||||
void debugDump() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
// disable these routines
|
||||
MemoryBlockManager();
|
||||
MemoryBlockManager(const MemoryBlockManager &);
|
||||
MemoryBlockManager &operator =(const MemoryBlockManager &);
|
||||
|
||||
public:
|
||||
|
||||
class Allocator;
|
||||
|
||||
private:
|
||||
|
||||
char const * m_name;
|
||||
bool m_shared;
|
||||
int m_currentNumberOfElements;
|
||||
Allocator * m_allocator;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline char const * MemoryBlockManager::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MemoryBlockManagerMacros.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_MemoryBlockManagerMacros_H
|
||||
#define INCLUDED_MemoryBlockManagerMacros_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class MemoryBlockManager;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define MEMORY_BLOCK_MANAGER_INTERFACE_WITH_INSTALL \
|
||||
public: \
|
||||
static void install(); \
|
||||
static void * operator new(size_t size); \
|
||||
static void * operator new(size_t size, void * placement); \
|
||||
static void operator delete(void * pointer); \
|
||||
private: \
|
||||
static void remove(); \
|
||||
static MemoryBlockManager * ms_memoryBlockManager
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#define MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITH_INSTALL(className, shared, elementsPerBlock, minimumNumberOfBlocks, maximumNumberOfBlocks) \
|
||||
void className::install() \
|
||||
{ \
|
||||
ms_memoryBlockManager = new MemoryBlockManager( #className " memoryBlockManager", shared, sizeof(className), elementsPerBlock, minimumNumberOfBlocks, maximumNumberOfBlocks); \
|
||||
ExitChain::add(&remove, #className "::remove"); \
|
||||
} \
|
||||
void className::remove() \
|
||||
{ \
|
||||
DEBUG_FATAL(!ms_memoryBlockManager,(#className " is not installed")); \
|
||||
delete ms_memoryBlockManager; \
|
||||
ms_memoryBlockManager = 0; \
|
||||
} \
|
||||
void * className::operator new(size_t size) \
|
||||
{ \
|
||||
UNREF(size); \
|
||||
DEBUG_FATAL(size != sizeof(className),("Incorrect allocation size for class " #className ": %d/%d", size, sizeof(className))); \
|
||||
DEBUG_FATAL(!ms_memoryBlockManager, (#className " is not installed")); \
|
||||
return ms_memoryBlockManager->allocate(); \
|
||||
} \
|
||||
void * className::operator new(size_t, void * placement) \
|
||||
{ \
|
||||
return placement; \
|
||||
}\
|
||||
void className::operator delete(void * pointer) \
|
||||
{ \
|
||||
DEBUG_FATAL(!ms_memoryBlockManager,(#className " is not installed")); \
|
||||
if (pointer) \
|
||||
ms_memoryBlockManager->free(pointer); \
|
||||
} \
|
||||
MemoryBlockManager * className::ms_memoryBlockManager
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define MEMORY_BLOCK_MANAGER_INTERFACE_WITHOUT_INSTALL \
|
||||
public: \
|
||||
static void * operator new(size_t size); \
|
||||
static void * operator new(size_t size, void * placement); \
|
||||
static void operator delete(void * pointer); \
|
||||
private: \
|
||||
static void installMemoryBlockManager(); \
|
||||
static void removeMemoryBlockManager(); \
|
||||
static MemoryBlockManager * ms_memoryBlockManager
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#define MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITHOUT_INSTALL(className, shared, elementsPerBlock, minimumNumberOfBlocks, maximumNumberOfBlocks) \
|
||||
void className::installMemoryBlockManager() \
|
||||
{ \
|
||||
ms_memoryBlockManager = new MemoryBlockManager( #className " memoryBlockManager", shared, sizeof(className), elementsPerBlock, minimumNumberOfBlocks, maximumNumberOfBlocks); \
|
||||
} \
|
||||
void className::removeMemoryBlockManager() \
|
||||
{ \
|
||||
DEBUG_FATAL(!ms_memoryBlockManager,(#className " is not installed")); \
|
||||
delete ms_memoryBlockManager; \
|
||||
ms_memoryBlockManager = 0; \
|
||||
} \
|
||||
void * className::operator new(size_t size) \
|
||||
{ \
|
||||
UNREF(size); \
|
||||
DEBUG_FATAL(size != sizeof(className),("Incorrect allocation size for class " #className ": %d/%d", size, sizeof(className))); \
|
||||
DEBUG_FATAL(!ms_memoryBlockManager, (#className " is not installed")); \
|
||||
return ms_memoryBlockManager->allocate(); \
|
||||
} \
|
||||
void * className::operator new(size_t, void * placement) \
|
||||
{ \
|
||||
return placement; \
|
||||
}\
|
||||
void className::operator delete(void * pointer) \
|
||||
{ \
|
||||
DEBUG_FATAL(!ms_memoryBlockManager,(#className " is not installed")); \
|
||||
if (pointer) \
|
||||
ms_memoryBlockManager->free(pointer); \
|
||||
} \
|
||||
MemoryBlockManager * className::ms_memoryBlockManager
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,319 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MessageQueue.cpp
|
||||
// Portions copyright 1998 Bootprint Entertainment.
|
||||
// Portions copyright 2000-2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/MessageQueue.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// ======================================================================
|
||||
// PUBLIC MessageQueue::Data
|
||||
// ======================================================================
|
||||
|
||||
MessageQueue::Data::Data()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
MessageQueue::Data::~Data()
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// PUBLIC MessageQueue::Notification
|
||||
// ======================================================================
|
||||
|
||||
MessageQueue::Notification::Notification()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
MessageQueue::Notification::~Notification()
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// PRIVATE MessageQueue::Message
|
||||
// ======================================================================
|
||||
|
||||
MessageQueue::Message::Message() :
|
||||
m_message(0),
|
||||
m_value(0),
|
||||
m_data(0),
|
||||
m_flags(0)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
MessageQueue::Message::~Message()
|
||||
{
|
||||
m_data = 0;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// PUBLIC MessageQueue
|
||||
// ======================================================================
|
||||
|
||||
MessageQueue::MessageQueue(const int initialSize) :
|
||||
m_messageQueue1(new MessageList),
|
||||
m_messageQueue2(new MessageList),
|
||||
m_messageQueueRead(m_messageQueue1),
|
||||
m_messageQueueWrite(m_messageQueue2),
|
||||
m_notification(0)
|
||||
{
|
||||
DEBUG_WARNING(initialSize < 0, ("initialSize < 0"));
|
||||
m_messageQueue1->reserve(static_cast<uint>(std::max(initialSize, 0)));
|
||||
m_messageQueue2->reserve(static_cast<uint>(std::max(initialSize, 0)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Destroy the MessageQueue.
|
||||
*/
|
||||
|
||||
MessageQueue::~MessageQueue()
|
||||
{
|
||||
clearDataFromMessageList(*m_messageQueue1, true);
|
||||
clearDataFromMessageList(*m_messageQueue2, true);
|
||||
delete m_messageQueue1;
|
||||
delete m_messageQueue2;
|
||||
m_messageQueueRead = 0;
|
||||
m_messageQueueWrite = 0;
|
||||
m_notification = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MessageQueue::clearDataFromMessageList(MessageList &messageList, bool destructor)
|
||||
{
|
||||
UNREF(destructor);
|
||||
MessageList::iterator iEnd = messageList.end();
|
||||
for (MessageList::iterator i = messageList.begin(); i != iEnd; ++i)
|
||||
{
|
||||
Message & message = *i;
|
||||
if (message.m_data)
|
||||
{
|
||||
DEBUG_WARNING(!destructor, ("clearing message data from beginFrame"));
|
||||
delete message.m_data;
|
||||
message.m_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get a message from the MessageQueue.
|
||||
*
|
||||
* The message index ranges from 0 to getNumberOfMessages()-1.
|
||||
*
|
||||
* @param index [In ] The index of the message to retrieve
|
||||
* @param message [Out] The message received
|
||||
* @param value [Out] Argument for the message
|
||||
* @param flags [Out] User flags for this message
|
||||
* @see MessageQueue::getNumberOfMessages()
|
||||
*/
|
||||
|
||||
void MessageQueue::getMessage(const int index, int *const message, float *const value, uint32 *const flags) const
|
||||
{
|
||||
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfMessages());
|
||||
NOT_NULL(message);
|
||||
NOT_NULL(value);
|
||||
NOT_NULL(m_messageQueueRead);
|
||||
|
||||
const Message ¤tMessage = (*m_messageQueueRead)[static_cast<uint>(index)];
|
||||
*message = currentMessage.m_message;
|
||||
*value = currentMessage.m_value;
|
||||
if (flags)
|
||||
*flags = currentMessage.m_flags;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Get a message from the MessageQueue.
|
||||
*
|
||||
* The message index ranges from 0 to getNumberOfMessages()-1.
|
||||
*
|
||||
* @param index [In ] The index of the message to retrieve
|
||||
* @param message [Out] The message received
|
||||
* @param value [Out] Argument for the message
|
||||
* @param data [Out] Data for the message
|
||||
* @param flags [Out] User flags for this message
|
||||
* @see MessageQueue::getNumberOfMessages()
|
||||
*/
|
||||
|
||||
void MessageQueue::getMessage(const int index, int *const message, float *const value, Data **const data, uint32 *const flags) const
|
||||
{
|
||||
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfMessages());
|
||||
NOT_NULL(message);
|
||||
NOT_NULL(value);
|
||||
NOT_NULL(data);
|
||||
NOT_NULL(m_messageQueueRead);
|
||||
|
||||
const Message & currentMessage = (*m_messageQueueRead)[static_cast<uint>(index)];
|
||||
*message = currentMessage.m_message;
|
||||
*value = currentMessage.m_value;
|
||||
*data = currentMessage.m_data;
|
||||
|
||||
if (flags)
|
||||
*flags = currentMessage.m_flags;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets message flags in the MessageQueue.
|
||||
*
|
||||
* The message index ranges from 0 to getNumberOfMessages()-1.
|
||||
*
|
||||
* @see MessageQueue::getNumberOfMessages()
|
||||
*/
|
||||
|
||||
void MessageQueue::setMessageFlags(const int index, const uint32 flags)
|
||||
{
|
||||
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfMessages());
|
||||
|
||||
(*m_messageQueueRead)[static_cast<uint>(index)].m_flags = flags;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Clear a message in the MessageQueue.
|
||||
*
|
||||
* The message index ranges from 0 to getNumberOfMessages()-1.
|
||||
*
|
||||
* @param index [In] The index of the message to clear
|
||||
* @see MessageQueue::getNumberOfMessages()
|
||||
*/
|
||||
|
||||
void MessageQueue::clearMessage(const int index)
|
||||
{
|
||||
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfMessages());
|
||||
|
||||
Message& message = (*m_messageQueueRead)[static_cast<uint>(index)];
|
||||
DEBUG_WARNING(message.m_data, ("MessageQueue::clearMessage - clearing message with non-null data"));
|
||||
message.m_message = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Clear a message in the MessageQueue.
|
||||
*
|
||||
* The message index ranges from 0 to getNumberOfMessages()-1.
|
||||
*
|
||||
* @param index [In] The index of the message data to clear
|
||||
* @see MessageQueue::getNumberOfMessages()
|
||||
*/
|
||||
|
||||
void MessageQueue::clearMessageData(const int index)
|
||||
{
|
||||
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfMessages());
|
||||
|
||||
Message& message = (*m_messageQueueRead)[static_cast<uint>(index)];
|
||||
message.m_data = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Append a new message to the MessageQueue.
|
||||
*
|
||||
* The message will not be retrievable until the next call to endFrame().
|
||||
*
|
||||
* @param message [In] Message to add to the MessageQueue
|
||||
* @param value [In] Value to be associated with the message
|
||||
* @param data [In] Data to be associated with the message
|
||||
* @param flags [In] User flags for this message
|
||||
*/
|
||||
|
||||
void MessageQueue::appendMessage(const int message, const float value, Data *const data, const uint32 flags)
|
||||
{
|
||||
if (message == 0)
|
||||
{
|
||||
WARNING_STRICT_FATAL(true, ("bad message"));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
//-- check to see if any message with data is already in the list
|
||||
if (data)
|
||||
{
|
||||
for (MessageList::iterator iter = m_messageQueueWrite->begin(); iter != m_messageQueueWrite->end(); ++iter)
|
||||
WARNING_STRICT_FATAL(iter->m_data == data, ("message queue data already in message queue"));
|
||||
}
|
||||
#endif
|
||||
|
||||
Message newMessage;
|
||||
newMessage.m_message = message;
|
||||
newMessage.m_value = value;
|
||||
newMessage.m_data = data;
|
||||
newMessage.m_flags = flags;
|
||||
m_messageQueueWrite->push_back(newMessage);
|
||||
|
||||
if (m_notification)
|
||||
m_notification->onChanged();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Append a new message to the MessageQueue.
|
||||
*
|
||||
* The message will not be retrievable until the next call to endFrame().
|
||||
*
|
||||
* @param message [In] Message to add to the MessageQueue
|
||||
* @param value [In] Value to be associated with the message
|
||||
* @param flags [In] User flags for this message
|
||||
*/
|
||||
|
||||
void MessageQueue::appendMessage(const int message, const float value, const uint32 flags)
|
||||
{
|
||||
appendMessage(message, value, 0, flags);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Get the number of messages in the current frame
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// The number of messages in the current frame for the MessageQueue.
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// getMessage() will take as indices the values from 0 the value returned
|
||||
// by this routine inclusive.
|
||||
//
|
||||
// See also:
|
||||
//
|
||||
// MessageQueue::getMessage()
|
||||
|
||||
int MessageQueue::getNumberOfMessages() const
|
||||
{
|
||||
return static_cast<int>(m_messageQueueRead->size());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MessageQueue::beginFrame()
|
||||
{
|
||||
//-- swap read and write
|
||||
std::swap (m_messageQueueRead, m_messageQueueWrite);
|
||||
|
||||
//-- clear write
|
||||
clearDataFromMessageList(*m_messageQueueWrite, false);
|
||||
m_messageQueueWrite->clear ();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void MessageQueue::setNotification(Notification* notification)
|
||||
{
|
||||
m_notification = notification;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,97 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// MessageQueue.h
|
||||
// Portions copyright 1998 Bootprint Entertainment.
|
||||
// Portions copyright 2000-2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_MessageQueue_H
|
||||
#define INCLUDED_MessageQueue_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class MessageQueue
|
||||
{
|
||||
public:
|
||||
|
||||
class Data
|
||||
{
|
||||
public:
|
||||
|
||||
Data();
|
||||
virtual ~Data()=0;
|
||||
};
|
||||
|
||||
class Notification
|
||||
{
|
||||
public:
|
||||
|
||||
Notification();
|
||||
virtual ~Notification()=0;
|
||||
|
||||
virtual void onChanged() const=0;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
explicit MessageQueue(int initialSize=0);
|
||||
~MessageQueue();
|
||||
|
||||
int getNumberOfMessages() const;
|
||||
void getMessage(int index, int *message, float *value, uint32 *flags=0) const;
|
||||
void getMessage(int index, int *message, float *value, Data **data, uint32 *flags=0) const;
|
||||
|
||||
void setMessageFlags(int index, uint32 flags);
|
||||
|
||||
void clearMessage(int index);
|
||||
void clearMessageData(int index);
|
||||
|
||||
void appendMessage(int message, float value, uint32 flags=0);
|
||||
void appendMessage(int message, float value, Data *data, uint32 flags=0);
|
||||
|
||||
void beginFrame();
|
||||
|
||||
void setNotification(Notification* notification);
|
||||
|
||||
private:
|
||||
|
||||
struct Message
|
||||
{
|
||||
public:
|
||||
|
||||
Message();
|
||||
~Message();
|
||||
|
||||
public:
|
||||
|
||||
int m_message;
|
||||
float m_value;
|
||||
Data *m_data;
|
||||
uint32 m_flags;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
typedef stdvector<Message>::fwd MessageList;
|
||||
|
||||
private:
|
||||
|
||||
MessageQueue(const MessageQueue &);
|
||||
MessageQueue &operator =(const MessageQueue &);
|
||||
|
||||
void clearDataFromMessageList(MessageList &messageList, bool destructor);
|
||||
|
||||
private:
|
||||
|
||||
MessageList *const m_messageQueue1;
|
||||
MessageList *const m_messageQueue2;
|
||||
MessageList *m_messageQueueRead;
|
||||
MessageList *m_messageQueueWrite;
|
||||
Notification *m_notification;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
//======================================================================
|
||||
//
|
||||
// MessageQueueDataTemplate.cpp
|
||||
// copyright (c) 2002 Sony Online Entertainment
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/MessageQueueDataTemplate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//======================================================================
|
||||
|
||||
MessageQueueDataTemplate<int> it;
|
||||
MessageQueueDataTemplate<std::string> st;
|
||||
|
||||
//======================================================================
|
||||
@@ -0,0 +1,57 @@
|
||||
//======================================================================
|
||||
//
|
||||
// MessageQueueDataTemplate.h
|
||||
// copyright (c) 2002 Sony Online Entertainment
|
||||
//
|
||||
//======================================================================
|
||||
|
||||
#ifndef INCLUDED_MessageQueueDataTemplate_H
|
||||
#define INCLUDED_MessageQueueDataTemplate_H
|
||||
|
||||
#include "sharedFoundation/MessageQueue.h"
|
||||
|
||||
//======================================================================
|
||||
|
||||
template <typename T> class MessageQueueDataTemplate :
|
||||
public MessageQueue::Data
|
||||
{
|
||||
public:
|
||||
|
||||
MessageQueueDataTemplate () :
|
||||
MessageQueue::Data (),
|
||||
m_data ()
|
||||
{
|
||||
}
|
||||
|
||||
explicit MessageQueueDataTemplate (const T & t) :
|
||||
MessageQueue::Data (),
|
||||
m_data (t)
|
||||
{
|
||||
}
|
||||
|
||||
const T & getData () const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
T & getData ()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void setData (const T & t) const
|
||||
{
|
||||
m_data = t;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
MessageQueueDataTemplate (const MessageQueueDataTemplate & rhs);
|
||||
MessageQueueDataTemplate & operator= (const MessageQueueDataTemplate & rhs);
|
||||
|
||||
T m_data;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,394 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Misc.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef MISC_H
|
||||
#define MISC_H
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Return the square of a number.
|
||||
*
|
||||
* This routine is templated, and implemented in terms of the * operator.
|
||||
*
|
||||
* @return The square of its argument
|
||||
*/
|
||||
template<class T>
|
||||
inline T sqr(
|
||||
const T &t // The number to square
|
||||
)
|
||||
{
|
||||
return (t * t);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Make sure value is between two values.
|
||||
*
|
||||
* This routine is templated, and implemented in terms of the > and > operators.
|
||||
*
|
||||
* @param minT Minimum variable
|
||||
* @param t Variable to clamp against min and max
|
||||
* @param maxT Minimum variable
|
||||
* @return If t is less than min, return min; if t is greater than max, return max
|
||||
* otherwise, return t
|
||||
*/
|
||||
|
||||
template<class T>inline const T clamp(const T &minT, const T &t, const T &maxT)
|
||||
{
|
||||
DEBUG_FATAL(maxT < minT, ("clamp error: max value is less than min value"));
|
||||
return (t < minT) ? minT : ((t > maxT) ? maxT : t);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* returns whether a value is within a given range, including the range end points.
|
||||
*
|
||||
* This routine will fatal in debug builds if max is less than min.
|
||||
*
|
||||
* @return True if value falls within the range min .. max, including min and max,
|
||||
* false otherwise.
|
||||
*/
|
||||
|
||||
template<class T>inline bool WithinRangeInclusiveInclusive(const T &rangeMin, const T &value, const T &rangeMax)
|
||||
{
|
||||
DEBUG_FATAL(rangeMax < rangeMin, ("range error: max value is less than min value"));
|
||||
return (value >= rangeMin) && (value <= rangeMax);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* returns whether a value is within a given range, excluding the range end points.
|
||||
*
|
||||
* This routine will fatal in debug builds if max is less than min.
|
||||
*
|
||||
* @return True if value falls within the range min .. max, not including min and max,
|
||||
* false otherwise.
|
||||
*/
|
||||
|
||||
template<class T>inline bool WithinRangeExclusiveExclusive(const T &rangeMin, const T &value, const T &rangeMax)
|
||||
{
|
||||
DEBUG_FATAL(rangeMax < rangeMin, ("range error: max value is less than min value"));
|
||||
return (value > rangeMin) && (value < rangeMax);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* returns true if a value falls within the range (base - epsilon) .. (base + epsilon),
|
||||
* including range endpoints.
|
||||
*
|
||||
* This routine will fatal during debug builds if epsilon is less than zero.
|
||||
*
|
||||
* @return true if value is within the range (base - epsilon) .. (base + epsilon), including
|
||||
* the range endpoints. Otherwise returns false.
|
||||
*/
|
||||
|
||||
template<class T>inline bool WithinEpsilonInclusive(const T &base, const T &value, const T &epsilon)
|
||||
{
|
||||
DEBUG_FATAL(epsilon < static_cast<T>(0), ("error: epsilon is less than zero"));
|
||||
return (value >= base - epsilon) && (value <= base + epsilon);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* returns true if a value falls within the range (base - epsilon) .. (base + epsilon),
|
||||
* excluding range endpoints.
|
||||
*
|
||||
* This routine will fatal during debug builds if epsilon is less than zero.
|
||||
*
|
||||
* @return true if value is within the range (base - epsilon) .. (base + epsilon), including
|
||||
* the range endpoints. Otherwise returns false.
|
||||
*/
|
||||
|
||||
template<class T>inline bool WithinEpsilonExclusive(const T &base, const T &value, const T &epsilon)
|
||||
{
|
||||
DEBUG_FATAL(epsilon < static_cast<T>(0), ("error: epsilon is less than zero"));
|
||||
return (value > base - epsilon) && (value < base + epsilon);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Zero out an object.
|
||||
*
|
||||
* This routine is templated.
|
||||
*
|
||||
* This routine will byte-zero fill the object which is passed to it.
|
||||
*
|
||||
* @param t The object to zero out
|
||||
*/
|
||||
|
||||
template<class T>inline void Zero(T &t)
|
||||
{
|
||||
memset(&t, 0, sizeof(t));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Duplicate a string.
|
||||
*
|
||||
* This routine allocates memory for a copy of its argument, copies
|
||||
* the source string into the new memory, and then returns a pointer to
|
||||
* the new memory.
|
||||
*
|
||||
* This routine will return NULL if called with NULL.
|
||||
*
|
||||
* @param source The string to copy
|
||||
* @return A pointer to a copy of the source argument
|
||||
*/
|
||||
|
||||
inline char *DuplicateString(const char *source)
|
||||
{
|
||||
if (!source)
|
||||
return NULL;
|
||||
|
||||
const uint length = strlen(source)+1;
|
||||
char *result = NON_NULL (new char[length]);
|
||||
memcpy(result, source, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Duplicate a string.
|
||||
*
|
||||
* This routine allocates memory for a copy of its argument, copies
|
||||
* the source string into the new memory, and then returns a pointer to
|
||||
* the new memory.
|
||||
*
|
||||
* This routine will return NULL if called with NULL.
|
||||
*
|
||||
* @param source The string to copy
|
||||
* @return A pointer to a copy of the source argument
|
||||
*/
|
||||
|
||||
inline char *DuplicateStringWithToLower(const char *source)
|
||||
{
|
||||
if (!source)
|
||||
return NULL;
|
||||
|
||||
const uint length = strlen(source)+1;
|
||||
char *result = NON_NULL (new char[length]);
|
||||
|
||||
for (uint i = 0; i < length; ++i)
|
||||
result[i] = static_cast<char>(tolower(source[i]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* memset with a integer length.
|
||||
*
|
||||
* This routine will
|
||||
*
|
||||
* @param data Location to fill at
|
||||
* @param value Vvalue to fill with
|
||||
* @param length Number of bytes to fill
|
||||
*/
|
||||
|
||||
inline void imemset(void *data, int value, int length)
|
||||
{
|
||||
DEBUG_FATAL(!data, ("null data arg"));
|
||||
memset(data, value, static_cast<uint>(length));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* memcpy with a integer length.
|
||||
*
|
||||
* This routine will
|
||||
*
|
||||
* @param destination Location to copy to
|
||||
* @param source Location to copy from
|
||||
* @param length Number of bytes to copy
|
||||
*/
|
||||
|
||||
inline void imemcpy(void *destination, const void *source, int length)
|
||||
{
|
||||
DEBUG_FATAL(!destination, ("null destination arg"));
|
||||
DEBUG_FATAL(!source, ("null source arg"));
|
||||
memcpy(destination, source, static_cast<uint>(length));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* memmove with a integer length.
|
||||
*
|
||||
* This routine will
|
||||
*
|
||||
* @param destination Location to copy to
|
||||
* @param source Location to copy from
|
||||
* @param length Number of bytes to copy
|
||||
*/
|
||||
|
||||
inline void *memmove(void *destination, const void *source, int length)
|
||||
{
|
||||
DEBUG_FATAL(!destination, ("null destination arg"));
|
||||
DEBUG_FATAL(!source, ("null source arg"));
|
||||
return memmove(destination, source, static_cast<uint>(length));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Returns the length of the string as an int.
|
||||
*
|
||||
* @param string String to compute the length
|
||||
* @return The length of the string as an int
|
||||
*/
|
||||
|
||||
inline int istrlen(const char *string)
|
||||
{
|
||||
DEBUG_FATAL(!string, ("null string arg"));
|
||||
return static_cast<int>(strlen(string));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Determine if a number is a power of two.
|
||||
*
|
||||
* This routine runs in O(1) time.
|
||||
*
|
||||
* @param value Value to see if it is a power of two
|
||||
* @return True if the value is a power of two, otherwise false
|
||||
*/
|
||||
|
||||
template<class T> inline bool IsPowerOfTwo(T value)
|
||||
{
|
||||
return ((value - 1) & (value)) == 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Returns the number of bits set in an integral type.
|
||||
*
|
||||
* Type T must provide integral-type bitwise operations and semantics.
|
||||
*
|
||||
* @param value Value to count the number of bits
|
||||
*/
|
||||
|
||||
template<class T> inline int GetBitCount(T value)
|
||||
{
|
||||
int count = 0;
|
||||
while (value)
|
||||
{
|
||||
value &= (value-1);
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Returns the index of the first bit set in an integral type.
|
||||
*
|
||||
* Type T must provide integral-type bitwise operations and semantics.
|
||||
*
|
||||
* @param value Value to find the first set bit
|
||||
* @return Returns the zero-based index of the first bit set in an
|
||||
* integral type, with the least significant byte being index 0.
|
||||
*
|
||||
* Returns -1 if no bits are set in the value.
|
||||
*/
|
||||
|
||||
template<class T>inline int GetFirstBitSet(T value)
|
||||
{
|
||||
if (!value)
|
||||
return -1;
|
||||
|
||||
int count;
|
||||
for (count = 0; !(value & static_cast<T>(0x01)); ++count, value >>= 1)
|
||||
{}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Calculate the factorial of the specified value.
|
||||
*
|
||||
* This routine takes O(n) time to compute.
|
||||
*
|
||||
* @param number The number to compute the factorial of
|
||||
* @return The factorial of the specified value
|
||||
*/
|
||||
|
||||
inline int factorial(int number)
|
||||
{
|
||||
int i, result;
|
||||
|
||||
for (result = 1, i = 2; i <= number; ++i)
|
||||
result *= i;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Calculate the number of combinations of i elements taken from a set of n elements.
|
||||
*
|
||||
* This routine computes: n! / (i! * (n-i)!).
|
||||
*
|
||||
* @param n Number of elements in the set
|
||||
* @param i Number of elements to pick from the set
|
||||
* @return The number of distinct combinations
|
||||
*/
|
||||
|
||||
inline int choose(int n, int i)
|
||||
{
|
||||
return factorial(n) / (factorial(i) * factorial(n - i));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Linear interpolate from start to end along t, where t is from 0..1.
|
||||
*
|
||||
* t must be from 0..1
|
||||
*
|
||||
* @return A value from start to end
|
||||
*/
|
||||
|
||||
template<class T> const T linearInterpolate (const T& start, const T& end, const real t)
|
||||
{
|
||||
return static_cast<T>((end - start) * t) + start;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* A non-linear, smooth interpolation from start to end along t, where t is from 0..1.
|
||||
*
|
||||
* (-2 * (end - start) * t^3) + (3 * (end - start) * t^2) + start
|
||||
*
|
||||
* t must be from 0..1
|
||||
*
|
||||
* @return A value from start to end
|
||||
*/
|
||||
|
||||
template<class T> const T cubicInterpolate(const T& start, const T& end, const real t)
|
||||
{
|
||||
real const tSquared = sqr(t);
|
||||
real const tCubed = tSquared * t;
|
||||
T const & diff = end - start;
|
||||
return static_cast<T>((diff * (tCubed * static_cast<real>(-2))) + (diff * (tSquared * static_cast<real>(3))) + start);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* A lint-friendly boolean compare.
|
||||
*
|
||||
* @return A value from start to end
|
||||
*/
|
||||
|
||||
inline bool boolEqual(bool const lhs, bool const rhs)
|
||||
{
|
||||
return (lhs && rhs) || (!lhs && !rhs);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// NetworkId.cpp
|
||||
// Copyright 2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const NetworkId NetworkId::cms_invalid(static_cast<NetworkIdType>(0));
|
||||
|
||||
// buildout network id occupies the sign bit in the 8 byte signed NetworkId (i.e. buildout network id is negative)
|
||||
// 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||
|
||||
// client side fake network id (in ClientObject.cpp) occupies the highest non-sign bit location in the 8 byte signed NetworkId
|
||||
// 01000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||
|
||||
// the 8 bit cluster id occupies these bit locations in the 8 byte NetworkId
|
||||
// 00111111 11000000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||
|
||||
// other network id will occupy the remaining bits
|
||||
// 00000000 00111111 11111111 11111111 11111111 11111111 11111111 11111111
|
||||
const NetworkId::NetworkIdType NetworkId::cms_maxNetworkIdWithoutClusterId(0x3FFFFFFFFFFFFFll);
|
||||
const NetworkId::NetworkIdType NetworkId::cms_networkIdWithoutClusterIdMask(0x403FFFFFFFFFFFFFll);
|
||||
const NetworkId::NetworkIdType NetworkId::cms_clusterIdMask(0x3FC0000000000000ll);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
NetworkId::NetworkId() :
|
||||
m_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
NetworkId::NetworkId(NetworkIdType value) :
|
||||
m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
NetworkId::NetworkId(const NetworkId& source) :
|
||||
m_value(source.getValue())
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
|
||||
NetworkId::~NetworkId()
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
std::string NetworkId::getValueString() const
|
||||
{
|
||||
char tmp[256];
|
||||
sprintf(tmp,INT64_FORMAT_SPECIFIER,m_value);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
NetworkId::NetworkId(const std::string &value) :
|
||||
m_value(0)
|
||||
{
|
||||
sscanf(value.c_str(),INT64_FORMAT_SPECIFIER,&m_value);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
NetworkId::NetworkIdType NetworkId::getValueWithClusterId(uint8 const clusterId, NetworkIdType const validForConversionMin, NetworkIdType const validForConversionMax) const
|
||||
{
|
||||
if ((m_value < validForConversionMin) || (m_value > validForConversionMax) || (clusterId == 0) || (m_value == 0))
|
||||
return m_value;
|
||||
|
||||
uint64 const uint64ClusterId = static_cast<uint64>(clusterId);
|
||||
return static_cast<NetworkId::NetworkIdType>((uint64ClusterId << 54) | static_cast<uint64>(m_value));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
NetworkId::NetworkIdType NetworkId::getValueWithoutClusterId() const
|
||||
{
|
||||
if (m_value <= cms_maxNetworkIdWithoutClusterId)
|
||||
return m_value;
|
||||
|
||||
return static_cast<NetworkId::NetworkIdType>(static_cast<uint64>(cms_networkIdWithoutClusterIdMask) & static_cast<uint64>(m_value));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
uint8 NetworkId::getValueClusterId() const
|
||||
{
|
||||
if (m_value <= cms_maxNetworkIdWithoutClusterId)
|
||||
return 0;
|
||||
|
||||
return static_cast<uint8>((static_cast<uint64>(cms_clusterIdMask) & static_cast<uint64>(m_value)) >> 54);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,168 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// NetworkId.h
|
||||
// Portions copyright 1999 Bootprint Entertainment
|
||||
// Copyright 2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_NetworkId_H
|
||||
#define INCLUDED_NetworkId_H
|
||||
|
||||
namespace DB
|
||||
{
|
||||
class BindableNetworkId;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class NetworkId
|
||||
{
|
||||
public:
|
||||
|
||||
typedef int64 NetworkIdType;
|
||||
|
||||
static const NetworkId cms_invalid;
|
||||
static const NetworkIdType cms_maxNetworkIdWithoutClusterId;
|
||||
static const NetworkIdType cms_networkIdWithoutClusterIdMask;
|
||||
static const NetworkIdType cms_clusterIdMask;
|
||||
struct Hash;
|
||||
friend struct NetworkId::Hash;
|
||||
|
||||
public:
|
||||
|
||||
NetworkId();
|
||||
explicit NetworkId(NetworkIdType value);
|
||||
explicit NetworkId(const std::string &value);
|
||||
NetworkId(const NetworkId&);
|
||||
|
||||
~NetworkId();
|
||||
|
||||
NetworkIdType getValueWithClusterId(uint8 clusterId, NetworkIdType validForConversionMin, NetworkIdType validForConversionMax) const;
|
||||
NetworkIdType getValueWithoutClusterId() const;
|
||||
uint8 getValueClusterId() const;
|
||||
NetworkIdType getValue() const;
|
||||
std::string getValueString() const;
|
||||
|
||||
NetworkId& operator= (const NetworkId&);
|
||||
bool operator< (const NetworkId& rhs) const;
|
||||
bool operator== (const NetworkId& rhs) const;
|
||||
bool operator!= (const NetworkId& rhs) const;
|
||||
size_t getHashValue() const;
|
||||
|
||||
bool isValid() const;
|
||||
bool operator !() const;
|
||||
|
||||
struct Hash
|
||||
{
|
||||
size_t operator()(const NetworkId & source) const
|
||||
{
|
||||
return source.getHashValue(); //TODO: make better hash function
|
||||
};
|
||||
};
|
||||
|
||||
private:
|
||||
NetworkIdType m_value;
|
||||
|
||||
friend class DB::BindableNetworkId;
|
||||
|
||||
private:
|
||||
explicit NetworkId(int value); // catch people who incorrectly try to construct one of these from an int
|
||||
// also makes constructing one of these from any other incorrect numeric type ambiguous
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline NetworkId::NetworkIdType NetworkId::getValue() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline NetworkId& NetworkId::operator= (const NetworkId& rhs)
|
||||
{
|
||||
m_value = rhs.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline bool NetworkId::operator< (const NetworkId& rhs) const
|
||||
{
|
||||
return m_value < rhs.m_value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline bool NetworkId::operator== (const NetworkId& rhs) const
|
||||
{
|
||||
return m_value == rhs.m_value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline bool NetworkId::operator!= (const NetworkId& rhs) const
|
||||
{
|
||||
return m_value != rhs.m_value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline bool NetworkId::isValid () const
|
||||
{
|
||||
return m_value != 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
inline bool NetworkId::operator! () const
|
||||
{
|
||||
return m_value == 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
inline size_t NetworkId::getHashValue () const
|
||||
{
|
||||
static uint32 const cs_randomValues[] =
|
||||
{
|
||||
0x904618ec,
|
||||
0x95c2f264,
|
||||
0xe55c30fe,
|
||||
0x2c92d2d1,
|
||||
0x8376930b,
|
||||
0x17662d70,
|
||||
0x2a785b31,
|
||||
0x1e7c7281,
|
||||
0x60bc4645,
|
||||
0x9a0cdf8f,
|
||||
0xa9bc133d,
|
||||
0x0e9a17ec,
|
||||
0xcd768a0d,
|
||||
0xe03e104f,
|
||||
0xecfab1bd,
|
||||
0x764a3a6f
|
||||
};
|
||||
|
||||
uint32 a = static_cast< uint32 >( m_value >> 32 );
|
||||
uint32 b = static_cast< uint32 >( m_value & 0xffffffff );
|
||||
return ( ( b * 0x10001 ) ^ a ) ^ cs_randomValues[ b & 0xf ] ; // multiply lower 32 by a large prime then XOR a then XOR some random value from table
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// STL standard hash function
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
struct hash<NetworkId> // stl standard hash
|
||||
{
|
||||
size_t operator()(const NetworkId &x) const { return x.getHashValue(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// NetworkIdArchive.cpp
|
||||
// Copyright 2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/NetworkIdArchive.h"
|
||||
|
||||
#include "Archive/ByteStream.h"
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void get(ReadIterator & source, uint64 & target)
|
||||
{
|
||||
source.get(&target, 8);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void put(ByteStream & target, const uint64 & source)
|
||||
{
|
||||
target.put(&source, 8);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void get(ReadIterator & source, int64 & target)
|
||||
{
|
||||
source.get(&target, 8);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void put(ByteStream & target, const int64 & source)
|
||||
{
|
||||
target.put(&source, 8);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void get(ReadIterator & source, NetworkId & target)
|
||||
{
|
||||
int64 id; // Using int64 instead of NetworkIdType so that we get a compile error if we change it
|
||||
//source.get(&id,8); // because this line hard-codes the size
|
||||
get(source, id);
|
||||
target = NetworkId(id);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void put(ByteStream & target, const NetworkId & source)
|
||||
{
|
||||
//uint64 tmp = source.getValue();
|
||||
put(target, source.getValue());
|
||||
//target.put(&tmp,8);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,33 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// NetworkIdArchive.h
|
||||
// Copyright 2001 Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_NetworkIdArchive_H
|
||||
#define INCLUDED_NetworkIdArchive_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class NetworkId;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace Archive
|
||||
{
|
||||
class ReadIterator;
|
||||
class ByteStream;
|
||||
|
||||
void get(ReadIterator & source, uint64 & target);
|
||||
void put(ByteStream & target, const uint64 & source);
|
||||
void get(ReadIterator & source, int64 & target);
|
||||
void put(ByteStream & target, const int64 & source);
|
||||
void get(ReadIterator & source, NetworkId & target);
|
||||
void put(ByteStream & target, const NetworkId & source);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,259 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PersistentCrcString.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/PersistentCrcString.h"
|
||||
|
||||
#include "sharedFoundation/Crc.h"
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/MemoryBlockManager.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
namespace PersistentCrcStringNamespace
|
||||
{
|
||||
void remove();
|
||||
|
||||
MemoryBlockManager * ms_fakeConstCharMemoryBlockManager = reinterpret_cast<MemoryBlockManager *>(0x01);
|
||||
MemoryBlockManager * ms_memoryBlockManager8;
|
||||
MemoryBlockManager * ms_memoryBlockManager16;
|
||||
MemoryBlockManager * ms_memoryBlockManager32;
|
||||
MemoryBlockManager * ms_memoryBlockManager48;
|
||||
MemoryBlockManager * ms_memoryBlockManager64;
|
||||
}
|
||||
using namespace PersistentCrcStringNamespace;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
PersistentCrcString const PersistentCrcString::empty("", CC_true);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void PersistentCrcString::install()
|
||||
{
|
||||
ms_memoryBlockManager8 = new MemoryBlockManager("PersistentCrcString8", true, 8, 0, 0, 0);
|
||||
ms_memoryBlockManager16 = new MemoryBlockManager("PersistentCrcString16", true, 16, 0, 0, 0);
|
||||
ms_memoryBlockManager32 = new MemoryBlockManager("PersistentCrcString32", true, 32, 0, 0, 0);
|
||||
ms_memoryBlockManager48 = new MemoryBlockManager("PersistentCrcString48", true, 48, 0, 0, 0);
|
||||
ms_memoryBlockManager64 = new MemoryBlockManager("PersistentCrcString64", true, 64, 0, 0, 0);
|
||||
ExitChain::add(PersistentCrcStringNamespace::remove, "PersistentCrcStringNamespace::remove");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PersistentCrcStringNamespace::remove()
|
||||
{
|
||||
delete ms_memoryBlockManager8;
|
||||
ms_memoryBlockManager8 = NULL;
|
||||
delete ms_memoryBlockManager16;
|
||||
ms_memoryBlockManager16 = NULL;
|
||||
delete ms_memoryBlockManager32;
|
||||
ms_memoryBlockManager32 = NULL;
|
||||
delete ms_memoryBlockManager48;
|
||||
ms_memoryBlockManager48 = NULL;
|
||||
delete ms_memoryBlockManager64;
|
||||
ms_memoryBlockManager64 = NULL;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
PersistentCrcString::PersistentCrcString()
|
||||
: CrcString(),
|
||||
m_memoryBlockManager(NULL),
|
||||
m_buffer(NULL)
|
||||
{
|
||||
DEBUG_FATAL(!ms_memoryBlockManager8, ("Constructing a PersistentCrcString before the class is installed"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString::PersistentCrcString(CrcString const &rhs)
|
||||
: CrcString(),
|
||||
m_memoryBlockManager(NULL),
|
||||
m_buffer(NULL)
|
||||
{
|
||||
DEBUG_FATAL(!ms_memoryBlockManager8, ("Constructing a PersistentCrcString before the class is installed"));
|
||||
|
||||
if (!rhs.isEmpty())
|
||||
PersistentCrcString::set(rhs.getString(), rhs.getCrc());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString::PersistentCrcString(PersistentCrcString const &rhs)
|
||||
: CrcString(), //lint !e1738 // non copy constructor used to initialize base class // this appears to be intentional.
|
||||
m_memoryBlockManager(NULL),
|
||||
m_buffer(NULL)
|
||||
{
|
||||
DEBUG_FATAL(!ms_memoryBlockManager8, ("Constructing a PersistentCrcString before the class is installed"));
|
||||
|
||||
if (!rhs.isEmpty())
|
||||
PersistentCrcString::set(rhs.getString(), rhs.getCrc());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString::PersistentCrcString(char const * string, bool applyNormalize)
|
||||
: CrcString(),
|
||||
m_memoryBlockManager(NULL),
|
||||
m_buffer(NULL)
|
||||
{
|
||||
DEBUG_FATAL(!ms_memoryBlockManager8, ("Constructing a PersistentCrcString before the class is installed"));
|
||||
|
||||
if (string)
|
||||
PersistentCrcString::set(string, applyNormalize);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString::PersistentCrcString(char const * string, uint32 crc)
|
||||
: CrcString(),
|
||||
m_memoryBlockManager(NULL),
|
||||
m_buffer(NULL)
|
||||
{
|
||||
DEBUG_FATAL(!ms_memoryBlockManager8, ("Constructing a PersistentCrcString before the class is installed"));
|
||||
|
||||
NOT_NULL(string);
|
||||
PersistentCrcString::set(string, crc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString::PersistentCrcString(char const * string, ConstChar)
|
||||
: CrcString(),
|
||||
m_memoryBlockManager(ms_fakeConstCharMemoryBlockManager),
|
||||
m_buffer(const_cast<char *>(string))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
DEBUG_FATAL(strlen(string)+1 >= Os::MAX_PATH_LENGTH, ("source string too long %d/%d",strlen(string)+1, Os::MAX_PATH_LENGTH));
|
||||
char buffer[Os::MAX_PATH_LENGTH];
|
||||
normalize(buffer, string);
|
||||
DEBUG_FATAL(strcmp(string, buffer) != 0, ("source string was not normalized"));
|
||||
#endif
|
||||
|
||||
calculateCrc();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString::~PersistentCrcString()
|
||||
{
|
||||
if (!ms_memoryBlockManager8 && m_memoryBlockManager && m_memoryBlockManager != ms_fakeConstCharMemoryBlockManager)
|
||||
{
|
||||
DEBUG_FATAL(true, ("Destructing a PersistentCrcString after the class was removed"));
|
||||
}
|
||||
|
||||
internalFree();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
char const * PersistentCrcString::getString() const
|
||||
{
|
||||
return m_buffer ? m_buffer : "";
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PersistentCrcString::internalFree()
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
if (m_memoryBlockManager)
|
||||
{
|
||||
if (m_memoryBlockManager == ms_fakeConstCharMemoryBlockManager)
|
||||
{
|
||||
m_memoryBlockManager = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_memoryBlockManager->free(m_buffer);
|
||||
m_memoryBlockManager = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
delete [] m_buffer;
|
||||
|
||||
m_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PersistentCrcString::clear()
|
||||
{
|
||||
internalFree();
|
||||
m_crc = Crc::crcNull;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PersistentCrcString::internalSet(char const * string, bool applyNormalize)
|
||||
{
|
||||
internalFree();
|
||||
|
||||
const int stringLength = istrlen(string) + 1;
|
||||
DEBUG_FATAL(stringLength > Os::MAX_PATH_LENGTH, ("string too long for a filename"));
|
||||
|
||||
m_memoryBlockManager = NULL;
|
||||
if (stringLength <= 8)
|
||||
m_memoryBlockManager = ms_memoryBlockManager8;
|
||||
else
|
||||
if (stringLength <= 16)
|
||||
m_memoryBlockManager = ms_memoryBlockManager16;
|
||||
else
|
||||
if (stringLength <= 32)
|
||||
m_memoryBlockManager = ms_memoryBlockManager32;
|
||||
else
|
||||
if (stringLength <= 48)
|
||||
m_memoryBlockManager = ms_memoryBlockManager48;
|
||||
else
|
||||
if (stringLength <= 64)
|
||||
m_memoryBlockManager = ms_memoryBlockManager64;
|
||||
|
||||
if (m_memoryBlockManager)
|
||||
m_buffer = reinterpret_cast<char *>(m_memoryBlockManager->allocate());
|
||||
else
|
||||
m_buffer = new char[static_cast<size_t>(stringLength)];
|
||||
|
||||
if (applyNormalize)
|
||||
normalize(m_buffer, string);
|
||||
else
|
||||
strcpy(m_buffer, string);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PersistentCrcString::set(char const * string, bool applyNormalize)
|
||||
{
|
||||
NOT_NULL(string);
|
||||
internalSet(string, applyNormalize);
|
||||
calculateCrc();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void PersistentCrcString::set(char const * string, uint32 crc)
|
||||
{
|
||||
NOT_NULL(string);
|
||||
internalSet(string, false);
|
||||
m_crc = crc;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
PersistentCrcString const & PersistentCrcString::operator=(PersistentCrcString const & rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
CrcString::set(rhs);
|
||||
|
||||
return *this;
|
||||
} //lint !e1539 //m_buffer not assigned
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,69 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PersistentCrcString.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PersistentCrcString_H
|
||||
#define INCLUDED_PersistentCrcString_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class MemoryBlockManager;
|
||||
#include "sharedFoundation/CrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class PersistentCrcString : public CrcString
|
||||
{
|
||||
public:
|
||||
|
||||
static PersistentCrcString const empty;
|
||||
|
||||
public:
|
||||
|
||||
static void install();
|
||||
|
||||
public:
|
||||
|
||||
PersistentCrcString();
|
||||
DLLEXPORT explicit PersistentCrcString(CrcString const & rhs);
|
||||
PersistentCrcString(PersistentCrcString const & rhs);
|
||||
PersistentCrcString(char const * string, bool applyNormalize);
|
||||
PersistentCrcString(char const * string, uint32 crc);
|
||||
|
||||
virtual DLLEXPORT ~PersistentCrcString();
|
||||
|
||||
virtual char const * getString() const;
|
||||
|
||||
virtual void clear();
|
||||
virtual void set(char const * string, bool applyNormalize);
|
||||
virtual void set(char const * string, uint32 crc);
|
||||
|
||||
PersistentCrcString const & operator=(PersistentCrcString const & rhs);
|
||||
|
||||
protected:
|
||||
|
||||
enum ConstChar
|
||||
{
|
||||
CC_true
|
||||
};
|
||||
|
||||
PersistentCrcString(char const * string, ConstChar);
|
||||
|
||||
private:
|
||||
|
||||
void internalFree();
|
||||
void internalSet(char const * string, bool applyNormalize);
|
||||
|
||||
private:
|
||||
|
||||
MemoryBlockManager * m_memoryBlockManager;
|
||||
char * m_buffer;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// PointerDeleter.h
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef POINTER_DELETER_H
|
||||
#define POINTER_DELETER_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include <utility>
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Delete the argument.
|
||||
*
|
||||
* The argument must be a pointer type.
|
||||
*/
|
||||
|
||||
class PointerDeleter
|
||||
{
|
||||
public:
|
||||
template <typename PointerType>
|
||||
void operator ()(PointerType pointer) const
|
||||
{
|
||||
delete pointer;
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Delete the argument using array-style deletion (i.e. delete [] object).
|
||||
*
|
||||
* The argument must be a pointer type.
|
||||
*/
|
||||
|
||||
class ArrayPointerDeleter
|
||||
{
|
||||
public:
|
||||
template <typename PointerType>
|
||||
void operator ()(PointerType pointer) const
|
||||
{
|
||||
delete [] pointer;
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Delete the argument's second member variable.
|
||||
*
|
||||
* The passed in argument must be of template type std::pair.
|
||||
*/
|
||||
|
||||
class PointerDeleterPairSecond
|
||||
{
|
||||
public:
|
||||
template <typename FirstType, typename SecondType>
|
||||
void operator ()(std::pair<FirstType, SecondType> &pairArgument) const
|
||||
{
|
||||
delete pairArgument.second;
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Delete the argument's second member variable using array-style deletion.
|
||||
*
|
||||
* The passed in argument must be of template type std::pair.
|
||||
*/
|
||||
|
||||
class ArrayPointerDeleterPairSecond
|
||||
{
|
||||
public:
|
||||
template <typename FirstType, typename SecondType>
|
||||
void operator ()(std::pair<FirstType, SecondType> &pairArgument) const
|
||||
{
|
||||
delete [] pairArgument.second;
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
//===================================================================
|
||||
//
|
||||
// Production.h
|
||||
// copyright 2002, sony online entertainment
|
||||
//
|
||||
//===================================================================
|
||||
|
||||
#ifndef INCLUDED_Production_H
|
||||
#define INCLUDED_Production_H
|
||||
|
||||
//===================================================================
|
||||
|
||||
#if DEBUG_LEVEL == 0
|
||||
#define PRODUCTION 1 //-- production
|
||||
#else
|
||||
#define PRODUCTION 0 //-- development
|
||||
#endif
|
||||
|
||||
//===================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// SafeCast.h
|
||||
// Copyright 2001, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_SafeCast_H
|
||||
#define INCLUDED_SafeCast_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#if DEBUG_LEVEL == DEBUG_LEVEL_RELEASE
|
||||
|
||||
#define safe_cast static_cast
|
||||
|
||||
#else
|
||||
|
||||
template <typename T, typename U>
|
||||
T safe_cast(U u)
|
||||
{
|
||||
if (!u)
|
||||
return 0;
|
||||
|
||||
T t = dynamic_cast<T>(u);
|
||||
NOT_NULL(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,203 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Scheduler.cpp
|
||||
// Copyright 2000 - 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Scheduler.h"
|
||||
#include "sharedFoundation/StaticCallbackEntry.h"
|
||||
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @brief construct a new Scheduler object
|
||||
|
||||
A system may have any number of schedulers running. Periodically
|
||||
invoke update(const unsigned long) on the Scheduler instance to
|
||||
trigger callback events.
|
||||
|
||||
\code
|
||||
class MyWorld
|
||||
{
|
||||
public:
|
||||
static void update()
|
||||
{
|
||||
instance().worldScheduler.update(Clock::timeMs());
|
||||
}
|
||||
private:
|
||||
static MyWorld & instance()
|
||||
{
|
||||
static MyWorld world;
|
||||
return world;
|
||||
}
|
||||
Scheduler worldScheduler;
|
||||
};
|
||||
|
||||
inst main(int, char **)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
MyWorld::update();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
Scheduler::Scheduler() :
|
||||
deferredCallbackEntryAdditions(new std::vector<StaticCallbackEntry *>),
|
||||
callbackQueue(new std::priority_queue<StaticCallbackEntry *, std::vector<StaticCallbackEntry *, std::allocator<StaticCallbackEntry *> >, StaticCallbackEntry::Compare>),
|
||||
currentCount(0),
|
||||
updating(false)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
Scheduler::~Scheduler()
|
||||
{
|
||||
StaticCallbackEntry * c;
|
||||
while(!callbackQueue->empty())
|
||||
{
|
||||
c = callbackQueue->top();
|
||||
delete c;
|
||||
callbackQueue->pop();
|
||||
}
|
||||
delete callbackQueue;
|
||||
|
||||
std::vector<StaticCallbackEntry *>::iterator i = deferredCallbackEntryAdditions->begin();
|
||||
for (; i != deferredCallbackEntryAdditions->end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
deferredCallbackEntryAdditions->clear();
|
||||
|
||||
delete deferredCallbackEntryAdditions;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
@brief Register a callback entry with the priority queue
|
||||
|
||||
Used internally in a few places to register StaticCallbackEntry object
|
||||
pointers with the CallbackEntrySet priority queue.
|
||||
|
||||
@param callback A StaticCallbackEntry object that contains callback
|
||||
information such as a callback function pointer and
|
||||
expire count.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
void Scheduler::addCallback(StaticCallbackEntry * callback)
|
||||
{
|
||||
// if the scheduler is in the middle of an update, ensure that
|
||||
// the callback is not added THIS frame (prevent infiniet callback loops
|
||||
// through long loop times or zero callback times)
|
||||
if(updating)
|
||||
deferredCallbackEntryAdditions->push_back(callback);
|
||||
else
|
||||
callbackQueue->push(callback);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
@brief The guts of the Scheduler. Request the next callback request
|
||||
for a static function.
|
||||
|
||||
The Scheduler may make callbacks on object member function pointers
|
||||
as well as static function pointers. When the Scheduler is updated
|
||||
with a value greater than (when + Scheduler::currentCount) it will
|
||||
invoke the supplied function.
|
||||
|
||||
@param cb a static function pointer
|
||||
@param context the context for the callback function.
|
||||
@param delay Used to calculate the expire count/time for the
|
||||
callback. The current count of the scheduler is
|
||||
added to 'delay', then the callback is inserted
|
||||
into the scheduler's priority queue, sorted by
|
||||
the calculated absolute time.
|
||||
|
||||
\code
|
||||
Scheduler globalScheduler;
|
||||
|
||||
void foo()
|
||||
{
|
||||
globalScheduler.setCallback(bar, 1000);
|
||||
}
|
||||
|
||||
void bar()
|
||||
{
|
||||
globalScheduler.setCallback(foo, 500);
|
||||
}
|
||||
\encode
|
||||
|
||||
@author Justin Randall
|
||||
|
||||
*/
|
||||
void Scheduler::setCallback(Callback cb, const void *context, unsigned long delay)
|
||||
{
|
||||
addCallback(new StaticCallbackEntry(getCurrentCount() + delay, cb, context));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @brief Trigger pending callbacks
|
||||
|
||||
A scheduler must be periodically updated to trigger callback events
|
||||
that are enqueued. A single unsigned long parameter is passed to the
|
||||
Scheduler indicating the current "time" or "frame" or some other
|
||||
value that ensures all callbacks with an expireCount value less than
|
||||
t will be triggered.
|
||||
|
||||
@param t The "time" or "frame" that triggers callbacks with expireCounts
|
||||
less than t.
|
||||
|
||||
\code
|
||||
int main(int, char **)
|
||||
{
|
||||
Scheduler s;
|
||||
while(1)
|
||||
{
|
||||
s.update(Clock::timeMs());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
void Scheduler::update(const unsigned long t)
|
||||
{
|
||||
// prevent recursive updates on a scheduler
|
||||
if(!updating)
|
||||
{
|
||||
updating = true;
|
||||
currentCount = t;
|
||||
StaticCallbackEntry * c;
|
||||
while( (!callbackQueue->empty()) && (c = callbackQueue->top())->getExpireCount() <= currentCount)
|
||||
{
|
||||
c->expired();
|
||||
delete c;
|
||||
callbackQueue->pop();
|
||||
}
|
||||
|
||||
updating = false;
|
||||
|
||||
if(!deferredCallbackEntryAdditions->empty())
|
||||
{
|
||||
std::vector<StaticCallbackEntry *>::iterator i;
|
||||
for(i = deferredCallbackEntryAdditions->begin(); i != deferredCallbackEntryAdditions->end(); ++i)
|
||||
{
|
||||
addCallback((*i));
|
||||
}
|
||||
deferredCallbackEntryAdditions->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,121 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Scheduler.h
|
||||
// Copyright 2000 - 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef _INCLUDED_Scheduler_H
|
||||
#define _INCLUDED_Scheduler_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/StaticCallbackEntry.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @brief Engine scheduler
|
||||
A scheduler is a priority queue containing callbacks, which in turn
|
||||
contain pointers to member functions which are executed when the
|
||||
callback is ready for processing.
|
||||
|
||||
The scheduler is updated with an arbitrary, unsigned long value. This
|
||||
value is used to examine a priority queue of callback entries. If
|
||||
the top element in the priority queue has an expireCount member that
|
||||
is less than the current count (passed to the scheduler update()),
|
||||
it is popped. If the object it refers to (or static callback function)
|
||||
is valid, it will invoke the requested callback.
|
||||
|
||||
This process is repeated until the top element in the priority queue
|
||||
has an expireCount greater than the current count.
|
||||
|
||||
To avoid infinite loops, a callback is never re-inserted in the
|
||||
queue during the queue update. If the Scheduler instance is updating,
|
||||
re-insertions are deferred, and the next earliest opportunity a
|
||||
callback could occur is during the NEXT update to the scheduler.
|
||||
|
||||
\code
|
||||
class MyObject : public Object
|
||||
{
|
||||
public:
|
||||
MyObject::MyObject() :
|
||||
{
|
||||
World::getObjectScheduler().setCallback(this, &MyObject::myExpireFunction, 1000);
|
||||
}
|
||||
|
||||
MyObject::~MyObject()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void myExpireFunction()
|
||||
{
|
||||
World::killObject(this); // destroy this object now!
|
||||
}
|
||||
};
|
||||
|
||||
void World::update()
|
||||
{
|
||||
// each MyObject will put itself on the world kill list
|
||||
// 1000 milliseconds after creation. They will be placed on
|
||||
// the list during the scheduler update when MyObject::myExpireFunction
|
||||
// is invoked.
|
||||
World::objectScheduler.update(Clock::timeMs());
|
||||
}
|
||||
\endcode
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
class Scheduler
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void (*Callback)(const void*);
|
||||
|
||||
public:
|
||||
|
||||
Scheduler();
|
||||
~Scheduler ();
|
||||
|
||||
void setCallback (Callback cb, const void *context, unsigned long delay);
|
||||
const unsigned long getCurrentCount () const;
|
||||
void update (const unsigned long currentCount);
|
||||
|
||||
private:
|
||||
|
||||
void addCallback(StaticCallbackEntry * callback);
|
||||
|
||||
// Disabled.
|
||||
Scheduler & operator = (const Scheduler & rhs);
|
||||
Scheduler(const Scheduler & source);
|
||||
|
||||
private:
|
||||
|
||||
stdvector<StaticCallbackEntry *>::fwd * deferredCallbackEntryAdditions;
|
||||
stdpriority_queue<StaticCallbackEntry *, std::vector<StaticCallbackEntry *, std::allocator<StaticCallbackEntry *> >, StaticCallbackEntry::Compare>::fwd * callbackQueue;
|
||||
|
||||
private:
|
||||
|
||||
unsigned long currentCount;
|
||||
bool updating;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/** @brief Return the current expire counter for the current/most recent
|
||||
update frame.
|
||||
|
||||
currentCount is updated when Scheduler::update() is invoked. It is set
|
||||
to the value of the update parameter. This value is used to determine
|
||||
which items in the priority queue should be executed next.
|
||||
|
||||
@author Justin Randall
|
||||
*/
|
||||
inline const unsigned long Scheduler::getCurrentCount() const
|
||||
{
|
||||
return currentCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_Scheduler_H
|
||||
@@ -0,0 +1,45 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// StaticCallbackEntry.cpp
|
||||
// Copyright 2000 - 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/StaticCallbackEntry.h"
|
||||
|
||||
#include "sharedFoundation/ExitChain.h"
|
||||
#include "sharedFoundation/MemoryBlockManager.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITH_INSTALL(StaticCallbackEntry, true, 0, 0, 0);
|
||||
|
||||
// ======================================================================
|
||||
|
||||
StaticCallbackEntry::StaticCallbackEntry(unsigned long when, Callback cb, const void *context) :
|
||||
m_expireCount(when),
|
||||
m_staticCallbackFunction(cb),
|
||||
m_context(context)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
StaticCallbackEntry::~StaticCallbackEntry()
|
||||
{
|
||||
// This instance doesn't own these pointers.
|
||||
m_staticCallbackFunction = 0;
|
||||
m_context = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void StaticCallbackEntry::expired() const
|
||||
{
|
||||
if(m_staticCallbackFunction)
|
||||
m_staticCallbackFunction(m_context);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,88 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// StaticCallbackEntry.h
|
||||
// Copyright 2000 - 2002 Sony Online Entertainment, Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef _INCLUDED_StaticCallbackEntry_H
|
||||
#define _INCLUDED_StaticCallbackEntry_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/MemoryBlockManagerMacros.h"
|
||||
|
||||
class MemoryBlockManager;
|
||||
|
||||
// ======================================================================
|
||||
/** @brief A class used by Scheduler to invoke a callback on a static
|
||||
function.
|
||||
*/
|
||||
|
||||
class StaticCallbackEntry
|
||||
{
|
||||
MEMORY_BLOCK_MANAGER_INTERFACE_WITH_INSTALL;
|
||||
|
||||
public:
|
||||
|
||||
typedef void (*Callback)(const void *context);
|
||||
|
||||
struct Compare
|
||||
{
|
||||
bool operator ()(const StaticCallbackEntry * lhs, const StaticCallbackEntry * rhs) const;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
StaticCallbackEntry(unsigned long when, Callback cb, const void *context);
|
||||
~StaticCallbackEntry();
|
||||
|
||||
unsigned long getExpireCount() const;
|
||||
void expired() const;
|
||||
|
||||
private:
|
||||
|
||||
struct StaticCallbackEntryFreeList;
|
||||
friend struct StaticCallbackEntryFreeList;
|
||||
|
||||
private:
|
||||
|
||||
static stdvector<StaticCallbackEntry *>::fwd & getStaticCallbackFreeList();
|
||||
|
||||
private:
|
||||
|
||||
// Disabled.
|
||||
StaticCallbackEntry(const StaticCallbackEntry &);
|
||||
StaticCallbackEntry & operator = (const StaticCallbackEntry &);
|
||||
|
||||
private:
|
||||
|
||||
unsigned long m_expireCount;
|
||||
Callback m_staticCallbackFunction;
|
||||
const void *m_context;
|
||||
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/** @return the expiration count ("time", "frame", whatever) of the callback.
|
||||
*/
|
||||
inline unsigned long StaticCallbackEntry::getExpireCount() const
|
||||
{
|
||||
return m_expireCount;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
inline bool StaticCallbackEntry::Compare::operator ()(const StaticCallbackEntry * lhs, const StaticCallbackEntry * rhs) const
|
||||
{
|
||||
NOT_NULL(lhs);
|
||||
NOT_NULL(rhs);
|
||||
|
||||
return lhs->getExpireCount() > rhs->getExpireCount();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // _INCLUDED_StaticCallbackEntry_H
|
||||
@@ -0,0 +1,17 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// StationId.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_StationId_H
|
||||
#define INCLUDED_StationId_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
typedef uint32 StationId;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,131 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// StlForwardDeclaration.h
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_StlForwardDeclaration_H
|
||||
#define INCLUDED_StlForwardDeclaration_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// Setup handling for template value defaults that require accessing the
|
||||
// {template type}::fwd value. gcc 3.2 requires typename here, gcc 2.95
|
||||
// optionally accepts typename here, msvc 6 will not accept it here.
|
||||
|
||||
#if defined(PLATFORM_WIN32) || defined(WIN32)
|
||||
|
||||
#define FORWARD_TYPENAME
|
||||
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
|
||||
#define FORWARD_TYPENAME typename
|
||||
|
||||
#else
|
||||
|
||||
#error unsupported platform
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
// grab stlport configuration
|
||||
#include "stl/_config.h"
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class _Tp> struct less;
|
||||
template <class _Tp> struct equal_to;
|
||||
template <class _T1, class _T2> struct pair;
|
||||
template <class _T1> struct hash;
|
||||
template <class _Tp> class allocator;
|
||||
template <class _CharT, class _Traits, class _Alloc> class basic_string;
|
||||
template <class _CharT> class char_traits;
|
||||
|
||||
template <size_t _Nb> class bitset;
|
||||
template <class _Tp, class _Alloc> class deque;
|
||||
template <class _Tp, class _Alloc> class list;
|
||||
template <class _Tp, class _Alloc> class queue;
|
||||
template <class _Tp, class _Alloc> class vector;
|
||||
template <class _Tp, class _Sequence> class stack;
|
||||
template <class _Tp, class _Container, class _Compare> class priority_queue;
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc> class map;
|
||||
template <class _Key, class _Tp, class _HashFcn, class _Compare, class _Alloc> class hash_map;
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc> class multimap;
|
||||
template <class _Key, class _Compare, class _Alloc> class set;
|
||||
template <class _Key, class _HashFcn, class _Compare, class _Alloc> class hash_set;
|
||||
template <class _Key, class _Compare, class _Alloc> class multiset;
|
||||
|
||||
typedef basic_string<char, char_traits<char>, allocator<char> > string;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc = std::allocator<_Tp> > struct stddeque
|
||||
{
|
||||
typedef std::deque<_Tp, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Alloc = std::allocator<_Tp> > struct stdlist
|
||||
{
|
||||
typedef std::list<_Tp, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Key, class _Tp, class _Compare = std::less<_Key>, class _Alloc = std::allocator< std::pair <const _Key, _Tp> > > struct stdmap
|
||||
{
|
||||
typedef std::map<_Key, _Tp, _Compare, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Key, class _Tp, class _HashFcn = std::hash<_Key>, class _Compare = std::equal_to<_Key>, class _Alloc = std::allocator< std::pair <const _Key, _Tp> > > struct stdhash_map
|
||||
{
|
||||
typedef std::hash_map<_Key, _Tp, _HashFcn, _Compare, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Key, class _Tp, class _Compare = std::less<_Key>, class _Alloc = std::allocator< std::pair <const _Key, _Tp> > > struct stdmultimap
|
||||
{
|
||||
typedef std::multimap<_Key, _Tp, _Compare, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Key, class _Compare = std::less<_Key>, class _Alloc = std::allocator<_Key> > struct stdset
|
||||
{
|
||||
typedef std::set<_Key, _Compare, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Key, class _HashFcn = std::hash<_Key>, class _Compare = std::equal_to<_Key>, class _Alloc = std::allocator<_Key> > struct stdhash_set
|
||||
{
|
||||
typedef std::hash_set<_Key, _HashFcn, _Compare, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Key, class _Compare = std::less<_Key>, class _Alloc = std::allocator<_Key> > struct stdmultiset
|
||||
{
|
||||
typedef std::multiset<_Key, _Compare, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Alloc = std::allocator<_Tp> > struct stdvector
|
||||
{
|
||||
typedef std::vector<_Tp, _Alloc> fwd;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Container = FORWARD_TYPENAME stdvector<_Tp>::fwd, class _Compare = std::less<typename _Container::value_type> > struct stdpriority_queue
|
||||
{
|
||||
typedef std::priority_queue<_Tp, _Container, _Compare> fwd;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Sequence = FORWARD_TYPENAME stddeque<_Tp>::fwd > struct stdqueue
|
||||
{
|
||||
typedef std::queue<_Tp, _Sequence> fwd;
|
||||
};
|
||||
|
||||
template <class _Tp, class _Sequence = FORWARD_TYPENAME stddeque<_Tp>::fwd > struct stdstack
|
||||
{
|
||||
typedef std::stack<_Tp, _Sequence> fwd;
|
||||
};
|
||||
|
||||
namespace Unicode
|
||||
{
|
||||
typedef unsigned short unicode_char_t;
|
||||
typedef std::basic_string<unicode_char_t, std::char_traits<unicode_char_t>, std::allocator<unicode_char_t> > String;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// StringCompare.h
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_StringCompare_H
|
||||
#define INCLUDED_StringCompare_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include <cstring>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/// A functor used to allow storing of char* in maps with value lookups
|
||||
class StringCompare
|
||||
{
|
||||
public:
|
||||
inline bool operator() (const char*, const char*) const;
|
||||
};
|
||||
|
||||
inline bool StringCompare::operator() (const char *lhs, const char *rhs) const
|
||||
{
|
||||
return static_cast<bool>(strcmp(lhs, rhs) < 0);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/// A functor used to allow storing of case insensitive char* in maps with value lookups
|
||||
class StringCaseCompare
|
||||
{
|
||||
public:
|
||||
inline bool operator() (const char*, const char*) const;
|
||||
};
|
||||
|
||||
inline bool StringCaseCompare::operator() (const char *lhs, const char *rhs) const
|
||||
{
|
||||
return static_cast<bool>(_stricmp(lhs, rhs) < 0);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,289 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Tag.h
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef TAG_H
|
||||
#define TAG_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define TAG_DIGIT_NULL 00
|
||||
#define TAG_DIGIT_SPACE 20
|
||||
|
||||
#define TAG_DIGIT_0 30
|
||||
#define TAG_DIGIT_1 31
|
||||
#define TAG_DIGIT_2 32
|
||||
#define TAG_DIGIT_3 33
|
||||
#define TAG_DIGIT_4 34
|
||||
#define TAG_DIGIT_5 35
|
||||
#define TAG_DIGIT_6 36
|
||||
#define TAG_DIGIT_7 37
|
||||
#define TAG_DIGIT_8 38
|
||||
#define TAG_DIGIT_9 39
|
||||
|
||||
#define TAG_DIGIT_A 41
|
||||
#define TAG_DIGIT_B 42
|
||||
#define TAG_DIGIT_C 43
|
||||
#define TAG_DIGIT_D 44
|
||||
#define TAG_DIGIT_E 45
|
||||
#define TAG_DIGIT_F 46
|
||||
#define TAG_DIGIT_G 47
|
||||
#define TAG_DIGIT_H 48
|
||||
#define TAG_DIGIT_I 49
|
||||
#define TAG_DIGIT_J 4A
|
||||
#define TAG_DIGIT_K 4B
|
||||
#define TAG_DIGIT_L 4C
|
||||
#define TAG_DIGIT_M 4D
|
||||
#define TAG_DIGIT_N 4E
|
||||
#define TAG_DIGIT_O 4F
|
||||
#define TAG_DIGIT_P 50
|
||||
#define TAG_DIGIT_Q 51
|
||||
#define TAG_DIGIT_R 52
|
||||
#define TAG_DIGIT_S 53
|
||||
#define TAG_DIGIT_T 54
|
||||
#define TAG_DIGIT_U 55
|
||||
#define TAG_DIGIT_V 56
|
||||
#define TAG_DIGIT_W 57
|
||||
#define TAG_DIGIT_X 58
|
||||
#define TAG_DIGIT_Y 59
|
||||
#define TAG_DIGIT_Z 5A
|
||||
|
||||
#define TAG_DIGIT__ 5f
|
||||
|
||||
#define TAG_DIGIT_a 61
|
||||
#define TAG_DIGIT_b 62
|
||||
#define TAG_DIGIT_c 63
|
||||
#define TAG_DIGIT_d 64
|
||||
#define TAG_DIGIT_e 65
|
||||
#define TAG_DIGIT_f 66
|
||||
#define TAG_DIGIT_g 67
|
||||
#define TAG_DIGIT_h 68
|
||||
#define TAG_DIGIT_i 69
|
||||
#define TAG_DIGIT_j 6A
|
||||
#define TAG_DIGIT_k 6B
|
||||
#define TAG_DIGIT_l 6C
|
||||
#define TAG_DIGIT_m 6D
|
||||
#define TAG_DIGIT_n 6E
|
||||
#define TAG_DIGIT_o 6F
|
||||
#define TAG_DIGIT_p 70
|
||||
#define TAG_DIGIT_q 71
|
||||
#define TAG_DIGIT_r 72
|
||||
#define TAG_DIGIT_s 73
|
||||
#define TAG_DIGIT_t 74
|
||||
#define TAG_DIGIT_u 75
|
||||
#define TAG_DIGIT_v 76
|
||||
#define TAG_DIGIT_w 77
|
||||
#define TAG_DIGIT_x 78
|
||||
#define TAG_DIGIT_y 79
|
||||
#define TAG_DIGIT_z 7A
|
||||
|
||||
// ======================================================================
|
||||
|
||||
typedef uint32 Tag;
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#define TAG_B(a,b,c,d) 0x ## a ## b ## c ## d
|
||||
#define TAG_A(a,b,c,d) static_cast<Tag>(TAG_B(a,b,c,d))
|
||||
#define TAG(a,b,c,d) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_ ## b, TAG_DIGIT_ ## c, TAG_DIGIT_ ## d)
|
||||
|
||||
#define TAG3(a,b,c) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_ ## b, TAG_DIGIT_ ## c, TAG_DIGIT_SPACE)
|
||||
#define TAG2(a,b) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_ ## b, TAG_DIGIT_SPACE, TAG_DIGIT_SPACE)
|
||||
#define TAG1(a) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_SPACE, TAG_DIGIT_SPACE, TAG_DIGIT_SPACE)
|
||||
|
||||
#define TAG03(a,b,c) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_ ## b, TAG_DIGIT_ ## c, TAG_DIGIT_NULL)
|
||||
#define TAG02(a,b) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_ ## b, TAG_DIGIT_NULL, TAG_DIGIT_NULL)
|
||||
#define TAG01(a) TAG_A(TAG_DIGIT_ ## a, TAG_DIGIT_NULL, TAG_DIGIT_NULL, TAG_DIGIT_NULL)
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* Convert a text string to a Tag
|
||||
*
|
||||
* This routine will convert a text string, such as "ABCD", to the tag value 'ABCD'.
|
||||
* If the string is less than 4 characters long, it will be padded with spaces.
|
||||
* If the string is greater than 4 characters long, it will be truncated.
|
||||
*
|
||||
* @param value string to convert to a Tag.
|
||||
*/
|
||||
|
||||
inline Tag ConvertStringToTag(const char *value)
|
||||
{
|
||||
Tag result = 0;
|
||||
|
||||
const int length = strlen(value);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const uint32 ch = static_cast<uint32>((i >= length) ? ' ' : value[i]);
|
||||
result = (result << 8) | ch;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert an integer to a Tag
|
||||
*
|
||||
* This routine will convert an int, such as 4, to the tag value '0004'.
|
||||
*
|
||||
* @param value value to convert to tag format
|
||||
*/
|
||||
|
||||
inline Tag ConvertIntToTag(int value)
|
||||
{
|
||||
Tag result = 0;
|
||||
|
||||
DEBUG_FATAL(value < 0 || value > 9999, ("value out of range 0/%d/9999", value));
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
const uint digit = static_cast<uint>(static_cast<int>(value % 10));
|
||||
value /= 10;
|
||||
result |= (digit + '0') << (i * 8);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Print the specified tag into a text buffer.
|
||||
*
|
||||
* This routine will fill the first four characters of the specified character
|
||||
* array with the name of the specified tag. If a character of the tag
|
||||
* is not printable, it will be replaced with a question mark.
|
||||
*
|
||||
* A null-character will be appended to the output buffer.
|
||||
*
|
||||
* This routine assumes the specified character buffer is at least 5 characters
|
||||
* in length.
|
||||
*
|
||||
* @param tag Tag to format
|
||||
* @param buffer Character array to format the tag into
|
||||
*/
|
||||
|
||||
inline void ConvertTagToString(Tag tag, char *buffer)
|
||||
{
|
||||
int i, j, ch;
|
||||
|
||||
DEBUG_FATAL(!buffer, ("buffer is null"));
|
||||
|
||||
for (i = 0, j = 24; i < 4; ++i, j -= 8)
|
||||
{
|
||||
ch = (static_cast<int>(tag) >> j) & 0xff; //lint !e702 // shift right of a signed quantity
|
||||
if (isprint(ch))
|
||||
buffer[i] = static_cast<char>(ch);
|
||||
else
|
||||
buffer[i] = '?';
|
||||
}
|
||||
|
||||
buffer[4] = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert the specified tag to an int.
|
||||
*
|
||||
* This routine will attempt to create an integer using as
|
||||
* many of least significant bytes of the tag as possible.
|
||||
*
|
||||
* Example: TAG(0,1,0,0) == 100
|
||||
* Example: TAG(1,R,1,0) == 10
|
||||
* Example: TAG(1,R,1,X) == 0
|
||||
*
|
||||
* @param tag Tag to format
|
||||
* @return Integer form of tag string.
|
||||
*/
|
||||
|
||||
inline int ConvertTagSuffixToInt(Tag tag)
|
||||
{
|
||||
int returnValue=0;
|
||||
for (int i=24;i>=0;i-=8)
|
||||
{
|
||||
const int c = (tag>>i) & 0xff;
|
||||
if (c>='0' && c<='9')
|
||||
{
|
||||
returnValue = returnValue*10 + int(c) -'0';
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue=0;
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Convert the specified tag to an int.
|
||||
*
|
||||
* This routine will attempt to create an integer from
|
||||
* a tag containing only numeric characters. If non-numeric
|
||||
* characters are detected, 0 is returned.
|
||||
*
|
||||
* Example: TAG(0,1,0,0) == 100
|
||||
* Example: TAG(1,R,1,0) == 0
|
||||
* Example: TAG(1,R,1,X) == 0
|
||||
*
|
||||
* @param tag Tag to format
|
||||
* @return Integer form of tag string.
|
||||
*/
|
||||
|
||||
inline int ConvertTagToInt(Tag tag)
|
||||
{
|
||||
int returnValue=0;
|
||||
for (int i=24;i>=0;i-=8)
|
||||
{
|
||||
const int c = (tag>>i) & 0xff;
|
||||
if (c>='0' && c<='9')
|
||||
{
|
||||
returnValue = returnValue*10 + int(c) -'0';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
const Tag TAG_0000 = TAG(0,0,0,0);
|
||||
const Tag TAG_0001 = TAG(0,0,0,1);
|
||||
const Tag TAG_0002 = TAG(0,0,0,2);
|
||||
const Tag TAG_0003 = TAG(0,0,0,3);
|
||||
const Tag TAG_0004 = TAG(0,0,0,4);
|
||||
const Tag TAG_0005 = TAG(0,0,0,5);
|
||||
const Tag TAG_0006 = TAG(0,0,0,6);
|
||||
const Tag TAG_0007 = TAG(0,0,0,7);
|
||||
const Tag TAG_0008 = TAG(0,0,0,8);
|
||||
const Tag TAG_0009 = TAG(0,0,0,9);
|
||||
const Tag TAG_0010 = TAG(0,0,1,0);
|
||||
const Tag TAG_0011 = TAG(0,0,1,1);
|
||||
const Tag TAG_0012 = TAG(0,0,1,2);
|
||||
const Tag TAG_0013 = TAG(0,0,1,3);
|
||||
const Tag TAG_0014 = TAG(0,0,1,4);
|
||||
const Tag TAG_0015 = TAG(0,0,1,5);
|
||||
|
||||
const Tag TAG_DATA = TAG(D,A,T,A);
|
||||
const Tag TAG_ENTR = TAG(E,N,T,R);
|
||||
const Tag TAG_FORM = TAG(F,O,R,M);
|
||||
const Tag TAG_INFO = TAG(I,N,F,O);
|
||||
|
||||
const Tag TAG_ARRY = TAG(A,R,R,Y);
|
||||
const Tag TAG_NAME = TAG(N,A,M,E);
|
||||
const Tag TAG_PARM = TAG(P,A,R,M);
|
||||
|
||||
//-- please do not add any Tags to this file unless they are generic
|
||||
//-- and expected to be used in many different contexts
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// TemporaryCrcString.cpp
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/TemporaryCrcString.h"
|
||||
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/Crc.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
TemporaryCrcString::TemporaryCrcString()
|
||||
: CrcString()
|
||||
{
|
||||
// this is to avoid including Os in the header file
|
||||
DEBUG_FATAL(static_cast<int>(BUFFER_SIZE) != static_cast<int>(Os::MAX_PATH_LENGTH), ("Os::MAX_PATH_LENGTH and BUFFER_SIZE differ"));
|
||||
|
||||
m_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* TRF needed this to allow useful sanity checking with std::set<TemporaryCrcString>.
|
||||
*/
|
||||
TemporaryCrcString::TemporaryCrcString(const TemporaryCrcString &rhs)
|
||||
: CrcString()
|
||||
{
|
||||
set(rhs.getString(), rhs.getCrc());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
TemporaryCrcString::TemporaryCrcString(char const * string, bool applyNormalize)
|
||||
: CrcString()
|
||||
{
|
||||
// this is to avoid including Os in the header file
|
||||
DEBUG_FATAL(static_cast<int>(BUFFER_SIZE) != static_cast<int>(Os::MAX_PATH_LENGTH), ("Os::MAX_PATH_LENGTH and BUFFER_SIZE differ"));
|
||||
|
||||
set(string, applyNormalize);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
TemporaryCrcString::TemporaryCrcString(char const * string, uint32 crc)
|
||||
: CrcString()
|
||||
{
|
||||
// this is to avoid including Os in the header file
|
||||
DEBUG_FATAL(static_cast<int>(BUFFER_SIZE) != static_cast<int>(Os::MAX_PATH_LENGTH), ("Os::MAX_PATH_LENGTH and BUFFER_SIZE differ"));
|
||||
|
||||
set(string, crc);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
TemporaryCrcString::~TemporaryCrcString()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
char const * TemporaryCrcString::getString() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void TemporaryCrcString::clear()
|
||||
{
|
||||
m_buffer[0] = '\0';
|
||||
m_crc = Crc::crcNull;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void TemporaryCrcString::internalSet(char const * string, bool applyNormalize)
|
||||
{
|
||||
DEBUG_FATAL(strlen(string)+1 > BUFFER_SIZE, ("string too long %d/%d", strlen(string)+1, BUFFER_SIZE));
|
||||
if (applyNormalize)
|
||||
normalize(m_buffer, string);
|
||||
else
|
||||
strcpy(m_buffer, string);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void TemporaryCrcString::set(char const * string, bool applyNormalize)
|
||||
{
|
||||
NOT_NULL(string);
|
||||
internalSet(string, applyNormalize);
|
||||
calculateCrc();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void TemporaryCrcString::set(char const * string, uint32 crc)
|
||||
{
|
||||
NOT_NULL(string);
|
||||
internalSet(string, false);
|
||||
m_crc = crc;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,55 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// TemporaryCrcString.h
|
||||
// Copyright 2002, Sony Online Entertainment Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_TemporaryCrcString_H
|
||||
#define INCLUDED_TemporaryCrcString_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/CrcString.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class TemporaryCrcString : public CrcString
|
||||
{
|
||||
public:
|
||||
|
||||
TemporaryCrcString();
|
||||
TemporaryCrcString(const TemporaryCrcString &);
|
||||
DLLEXPORT TemporaryCrcString(const char *string, bool applyNormalize);
|
||||
TemporaryCrcString(const char *string, uint32 crc);
|
||||
|
||||
virtual DLLEXPORT ~TemporaryCrcString();
|
||||
|
||||
virtual const char *getString() const;
|
||||
|
||||
virtual void clear();
|
||||
virtual void set(const char *string, bool applyNormalize);
|
||||
virtual void set(const char *string, uint32 crc);
|
||||
|
||||
private:
|
||||
|
||||
TemporaryCrcString & operator =(const TemporaryCrcString &);
|
||||
|
||||
void internalSet(const char *string, bool applyNormalize);
|
||||
|
||||
private:
|
||||
|
||||
enum
|
||||
{
|
||||
BUFFER_SIZE = 512
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
char m_buffer[BUFFER_SIZE];
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Timer.cpp
|
||||
// jeff grills
|
||||
//
|
||||
// copyright 1998 Bootprint Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/Timer.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void Timer::setElapsedTime(float seconds)
|
||||
{
|
||||
time = seconds;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,309 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Timer.h
|
||||
// Copyright 1998 Bootprint Entertainment
|
||||
// Copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Timer_H
|
||||
#define INCLUDED_Timer_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* Convienent countdown timer class.
|
||||
*
|
||||
* Timer objects do not automatically update off the clock. They must be
|
||||
* told that time is elapsing by calling one of the update*() functions.
|
||||
* The update routine will return true when the timer expires.
|
||||
*/
|
||||
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
|
||||
Timer();
|
||||
explicit Timer(real seconds);
|
||||
Timer(const Timer &rhs);
|
||||
Timer &operator =(const Timer &rhs);
|
||||
|
||||
void setExpireTime(real seconds);
|
||||
void extendExpireTime(real seconds);
|
||||
|
||||
void reset();
|
||||
void setElapsedTime(float seconds);
|
||||
|
||||
bool updateNoReset(real elapsedTime);
|
||||
bool updateZero(real elapsedTime);
|
||||
bool updateSubtract(real elapsedTime);
|
||||
|
||||
bool isExpired() const;
|
||||
real getExpireTime() const;
|
||||
real getElapsedRatio() const;
|
||||
real getRemainingRatio() const;
|
||||
real getExpirationOvershoot() const;
|
||||
real getRemainingTime() const;
|
||||
|
||||
private:
|
||||
|
||||
real expireTime;
|
||||
real time;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/** Construct a timer object
|
||||
*
|
||||
* The timer is constructed with the belief that no time has elapsed.
|
||||
* This constructor will set the expire-time to 0.
|
||||
*/
|
||||
|
||||
inline Timer::Timer()
|
||||
: expireTime(0),
|
||||
time(0)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Construct a timer object.
|
||||
*
|
||||
* The timer is constructed with the belief that no time has elapsed.
|
||||
*
|
||||
* @param seconds Time (in seconds) that the timer should expire at
|
||||
*/
|
||||
|
||||
inline Timer::Timer(real seconds)
|
||||
: expireTime(seconds),
|
||||
time(0)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Construct a timer object.
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
|
||||
inline Timer::Timer(const Timer &rhs)
|
||||
: expireTime(rhs.expireTime),
|
||||
time(rhs.time)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Assignment operator.
|
||||
*
|
||||
* Assignment operator.
|
||||
*/
|
||||
|
||||
inline Timer &Timer::operator =(const Timer &rhs)
|
||||
{
|
||||
// if (this != &rhs)
|
||||
{
|
||||
expireTime = rhs.expireTime;
|
||||
time = rhs.time;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Set a new expire time for the timer.
|
||||
*
|
||||
* This routine changes the time at which the timer will expire. It has
|
||||
* no effect on the amount of time that the timer believes has already
|
||||
* elapsed.
|
||||
*
|
||||
* @param seconds Time (in seconds) that the timer should expire at
|
||||
*/
|
||||
|
||||
inline void Timer::setExpireTime(real seconds)
|
||||
{
|
||||
expireTime = seconds;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Extends the expire time for the timer.
|
||||
*
|
||||
* This routine changes the time at which the timer will expire. It has
|
||||
* no effect on the amount of time that the timer believes has already
|
||||
* elapsed.
|
||||
*
|
||||
* @param seconds Time (in seconds) to add to the current expire time
|
||||
*/
|
||||
|
||||
inline void Timer::extendExpireTime(real seconds)
|
||||
{
|
||||
expireTime += seconds;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Reset the timer.
|
||||
*
|
||||
* This resets the timer to believe that no time has elapsed.
|
||||
*/
|
||||
|
||||
inline void Timer::reset()
|
||||
{
|
||||
time = 0.0f;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Inform the timer that time has elapsed, but not not reset the timer.
|
||||
*
|
||||
* When the timer expires, it will remain expired until reset() is called
|
||||
* or one of the update*() functions is called that will reduce the amount
|
||||
* of elapsed time.
|
||||
*
|
||||
* @param elapsedTime Amount of time (in seconds) that has elapsed
|
||||
* @return True if the timer has expired, false otherwise.
|
||||
* @see Timer::reset(), Timer::updateZero(), Timer::updateSubtract()
|
||||
*/
|
||||
|
||||
inline bool Timer::updateNoReset(real elapsedTime)
|
||||
{
|
||||
time += elapsedTime;
|
||||
return (time >= expireTime);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Inform the timer that time has elapsed, and reset the time if it expired.
|
||||
*
|
||||
* When this routine detects the timer has expired, it will reset the timer.
|
||||
* This will guarentee at least the amount of time has passed between
|
||||
* expirations, but will not necessarily behave properly over an extended
|
||||
* period of time.
|
||||
*
|
||||
* @return True if the timer has expired, false otherwise.
|
||||
* @see Timer::reset(), Timer::updateNoReset(), Timer::updateSubtract()
|
||||
*/
|
||||
|
||||
inline bool Timer::updateZero(real elapsedTime)
|
||||
{
|
||||
if (updateNoReset(elapsedTime))
|
||||
{
|
||||
reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Inform the timer that time has elapsed, and reduce the time if it expired.
|
||||
*
|
||||
* When this routine detects the timer has expired, it will subtract the
|
||||
* timer expiration time from the current time value. This routine will
|
||||
* tend to remain more accurate over a longer period of time, but will
|
||||
* not necessarily guarentee that the specified time will elapse before the
|
||||
* next expiration (because of carry-over from the previous update).
|
||||
*
|
||||
* @return True if the timer has expired, false otherwise.
|
||||
* @see Timer::reset(), Timer::updateNoReset(), Timer::updateSubtract()
|
||||
*/
|
||||
|
||||
inline bool Timer::updateSubtract(real elapsedTime)
|
||||
{
|
||||
if (updateNoReset(elapsedTime))
|
||||
{
|
||||
time -= expireTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Check if the timer is expired.
|
||||
*
|
||||
* This routine does not update the timer's current time.
|
||||
*
|
||||
* @return true if the timer has expired, otherwise false.
|
||||
*/
|
||||
|
||||
inline bool Timer::isExpired() const
|
||||
{
|
||||
return time >= expireTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the expire time
|
||||
*
|
||||
* @return expire time
|
||||
*/
|
||||
|
||||
inline real Timer::getExpireTime() const
|
||||
{
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Calculate ratio (from 0 to 1) of time elapsed.
|
||||
*
|
||||
* Should not be called if the expire time has not been set, as the result
|
||||
* is undefined.
|
||||
*
|
||||
* @return ratio (from 0 to 1) of time elapsed
|
||||
*/
|
||||
|
||||
inline real Timer::getElapsedRatio() const
|
||||
{
|
||||
return expireTime != 0.0f ? time / expireTime : 0.0f;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Calculate ratio (from 0 to 1) of time remaining.
|
||||
*
|
||||
* Should not be called if the expire time has not been set, as the result
|
||||
* is undefined.
|
||||
*
|
||||
* @return ratio (from 0 to 1) of time remaining
|
||||
*/
|
||||
|
||||
inline real Timer::getRemainingRatio() const
|
||||
{
|
||||
return expireTime != 0.0f ? ((expireTime - time) / expireTime) : 0.0f;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the amount of time beyond the expiration time we are.
|
||||
*
|
||||
* The value returned is negative if we haven't expired yet.
|
||||
*
|
||||
* @return the overshoot time
|
||||
*/
|
||||
|
||||
inline real Timer::getExpirationOvershoot() const
|
||||
{
|
||||
return time - expireTime;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
/**
|
||||
* Return the amount of time until expiration.
|
||||
*
|
||||
* @return the overshoot time
|
||||
*/
|
||||
|
||||
inline real Timer::getRemainingTime() const
|
||||
{
|
||||
return expireTime - time;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// VoidBindSecond.h
|
||||
// copyright 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include <functional>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
template <class Operation>
|
||||
class VoidBinderSecond: public std::unary_function<typename Operation::first_argument_type, void>
|
||||
{
|
||||
private:
|
||||
|
||||
typename Operation::second_argument_type m_boundValue;
|
||||
Operation m_operation;
|
||||
|
||||
public:
|
||||
|
||||
VoidBinderSecond(const Operation& operation, const typename Operation::second_argument_type &boundValue)
|
||||
: m_operation(operation), m_boundValue(boundValue) {}
|
||||
|
||||
void operator()(const typename Operation::first_argument_type& argument) const
|
||||
{
|
||||
m_operation(argument, m_boundValue);
|
||||
}
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
/**
|
||||
* works just like std::bind2nd() when return value of function is void.
|
||||
*
|
||||
* this is necessary since our STL breaks under MSVC 6 when using void functions
|
||||
* with bind2nd.
|
||||
*/
|
||||
|
||||
|
||||
template <class Operation, typename BindArgumentType>
|
||||
inline VoidBinderSecond<Operation> VoidBindSecond(const Operation& operation, const BindArgumentType &bindArgument)
|
||||
{
|
||||
typedef typename Operation::second_argument_type SecondArgumentType;
|
||||
|
||||
return VoidBinderSecond<Operation>(operation, SecondArgumentType(bindArgument));
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user