Added sharedGame sharedMathArchive and sharedUtility libraries

This commit is contained in:
Anonymous
2014-01-14 08:01:40 -07:00
parent 3cbcb5cd28
commit 2931511f72
604 changed files with 76602 additions and 0 deletions
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 2.8)
project(sharedUtility)
if(WIN32)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public)
add_subdirectory(src)
@@ -0,0 +1 @@
#include "../../src/shared/BakedTerrain.h"
@@ -0,0 +1 @@
#include "../../src/shared/BakedTerrainReader.h"
@@ -0,0 +1 @@
#include "../../src/shared/CachedFileManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/Callback.h"
@@ -0,0 +1 @@
#include "../../src/shared/CallbackReceiver.h"
@@ -0,0 +1 @@
#include "../../src/shared/ConfigSharedUtility.h"
@@ -0,0 +1 @@
#include "../../src/shared/CurrentUserOptionManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/DataTable.h"
@@ -0,0 +1 @@
#include "../../src/shared/DataTableCell.h"
@@ -0,0 +1 @@
#include "../../src/shared/DataTableColumnType.h"
@@ -0,0 +1 @@
#include "../../src/shared/DataTableManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/DataTableWriter.h"
@@ -0,0 +1 @@
#include "../../src/shared/FileName.h"
@@ -0,0 +1 @@
#include "../../src/shared/FirstSharedUtility.h"
@@ -0,0 +1 @@
#include "../../src/shared/HttpGetEncoder.h"
@@ -0,0 +1 @@
#include "../../src/shared/IndexedCache.h"
@@ -0,0 +1 @@
#include "../../src/shared/InstallationResourceData.h"
@@ -0,0 +1 @@
#include "../../src/shared/InstallationResourceDataArchive.h"
@@ -0,0 +1 @@
#include "../../src/shared/InteriorLayoutReaderWriter.h"
@@ -0,0 +1 @@
#include "../../src/shared/LocalMachineOptionManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/Location.h"
@@ -0,0 +1 @@
#include "../../src/shared/LocationArchive.h"
@@ -0,0 +1 @@
#include "../../src/shared/LocationManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/NameGenerator.h"
@@ -0,0 +1 @@
#include "../../src/shared/NetworkIdAutoDeltaPackedMap.h"
@@ -0,0 +1 @@
#include "../../src/shared/OptionManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/PackedFixedPointMap.h"
@@ -0,0 +1 @@
#include "../../src/shared/PackedIntegerMap.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PackedPosition.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PackedQuaternion.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PackedRotationRate.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PackedTransform.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PackedUnitVector.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PackedVelocity.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/PooledString.h"
@@ -0,0 +1 @@
#include "../../src/shared/RotaryCache.h"
@@ -0,0 +1 @@
#include "../../src/shared/SetupSharedUtility.h"
@@ -0,0 +1 @@
#include "../../src/shared/StartingLocationData.h"
@@ -0,0 +1 @@
#include "../../src/shared/StartingLocationDataArchive.h"
@@ -0,0 +1 @@
#include "../../src/shared/StartingLocationManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/SynchronizedWeatherGenerator.h"
@@ -0,0 +1 @@
#include "../../src/shared/TemplateParameter.h"
@@ -0,0 +1 @@
#include "../../src/shared/UniqueNameList.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueDictionary.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueDictionaryArchive.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueTypeBase.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueTypeBool.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueTypeFloat.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueTypeObjId.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueTypeSignedInt.h"
@@ -0,0 +1 @@
#include "../../src/shared/ValueTypeString.h"
@@ -0,0 +1 @@
#include "../../src/shared/WeatherData.h"
@@ -0,0 +1 @@
#include "../../src/shared/WorldSnapshotReaderWriter.h"
@@ -0,0 +1,122 @@
set(SHARED_SOURCES
shared/BakedTerrain.cpp
shared/BakedTerrain.h
shared/BakedTerrainReader.cpp
shared/BakedTerrainReader.h
shared/CachedFileManager.cpp
shared/CachedFileManager.h
shared/Callback.cpp
shared/Callback.h
shared/CallbackReceiver.h
shared/ConfigSharedUtility.cpp
shared/ConfigSharedUtility.h
shared/CurrentUserOptionManager.cpp
shared/CurrentUserOptionManager.h
shared/DataTable.cpp
shared/DataTable.h
shared/DataTableCell.cpp
shared/DataTableCell.h
shared/DataTableColumnType.cpp
shared/DataTableColumnType.h
shared/DataTableManager.cpp
shared/DataTableManager.h
shared/DataTableWriter.cpp
shared/DataTableWriter.h
shared/FileName.cpp
shared/FileName.h
shared/FirstSharedUtility.h
shared/HttpGetEncoder.cpp
shared/HttpGetEncoder.h
shared/IndexedCache.cpp
shared/IndexedCache.h
shared/InstallationResourceData.h
shared/InstallationResourceDataArchive.h
shared/InteriorLayoutReaderWriter.cpp
shared/InteriorLayoutReaderWriter.h
shared/Location.cpp
shared/Location.h
shared/LocationArchive.cpp
shared/LocationArchive.h
shared/LocalMachineOptionManager.cpp
shared/LocalMachineOptionManager.h
shared/LocationManager.cpp
shared/LocationManager.h
shared/NameGenerator.cpp
shared/NameGenerator.h
shared/NetworkIdAutoDeltaPackedMap.cpp
shared/NetworkIdAutoDeltaPackedMap.h
shared/OptionManager.cpp
shared/OptionManager.h
shared/PackedIntegerMap.cpp
shared/PackedIntegerMap.h
shared/PackedFixedPointMap.cpp
shared/PackedFixedPointMap.h
shared/PackedPosition.h
shared/PackedQuaternion.h
shared/PackedRotationRate.h
shared/PackedTransform.h
shared/PackedUnitVector.h
shared/PackedVelocity.h
shared/PooledString.cpp
shared/PooledString.h
shared/RotaryCache.cpp
shared/RotaryCache.h
shared/SetupSharedUtility.cpp
shared/SetupSharedUtility.h
shared/StartingLocationData.cpp
shared/StartingLocationData.h
shared/StartingLocationDataArchive.cpp
shared/StartingLocationDataArchive.h
shared/StartingLocationManager.cpp
shared/StartingLocationManager.h
shared/SynchronizedWeatherGenerator.cpp
shared/SynchronizedWeatherGenerator.h
shared/TemplateParameter.cpp
shared/TemplateParameter.h
shared/UniqueNameList.cpp
shared/UniqueNameList.h
shared/ValueDictionary.cpp
shared/ValueDictionary.h
shared/ValueDictionaryArchive.cpp
shared/ValueDictionaryArchive.h
shared/ValueTypeBase.cpp
shared/ValueTypeBase.h
shared/ValueTypeBool.cpp
shared/ValueTypeBool.h
shared/ValueTypeFloat.cpp
shared/ValueTypeFloat.h
shared/ValueTypeObjId.cpp
shared/ValueTypeObjId.h
shared/ValueTypeSignedInt.cpp
shared/ValueTypeSignedInt.h
shared/ValueTypeString.cpp
shared/ValueTypeString.h
shared/WeatherData.cpp
shared/WeatherData.h
shared/WorldSnapshotReaderWriter.cpp
shared/WorldSnapshotReaderWriter.h
)
if(WIN32)
set(PLATFORM_SOURCES
win32/FirstSharedUtility.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
else()
set(PLATFORM_SOURCES "")
endif()
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/shared
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
)
add_library(sharedUtility STATIC
${SHARED_SOURCES}
${PLATFORM_SOURCES}
)
@@ -0,0 +1,361 @@
//===================================================================
//
// BakedTerrain.cpp
// asommers
//
// copyright 2002, sony online entertainment
//
//===================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/BakedTerrain.h"
#include "sharedFile/Iff.h"
#include "sharedMath/Rectangle2d.h"
#include "sharedMath/Vector2d.h"
#include <algorithm>
//===================================================================
namespace
{
const Tag TAG_WMAP = TAG (W,M,A,P);
const Tag TAG_SMAP = TAG (S,M,A,P);
}
//===================================================================
// PUBLIC BakedTerrain
//===================================================================
BakedTerrain::BakedTerrain () :
m_mapWidthInMeters (0.f),
m_chunkWidthInMeters (0.f),
m_width (0),
m_height (0),
m_waterMap (0),
m_slopeMap (0)
{
}
//-------------------------------------------------------------------
BakedTerrain::~BakedTerrain ()
{
destroy ();
m_waterMap = 0;
m_slopeMap = 0;
}
//-------------------------------------------------------------------
void BakedTerrain::load (Iff& iff)
{
destroy ();
switch (iff.getCurrentName ())
{
case TAG_0000:
load_0000 (iff);
break;
case TAG_0001:
load_0001 (iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString (iff.getCurrentName (), tagBuffer);
char buffer [128];
iff.formatLocation (buffer, sizeof (buffer));
DEBUG_FATAL (true, ("invalid BakedTerrain version %s/%s", buffer, tagBuffer));
}
break;
}
}
//-------------------------------------------------------------------
void BakedTerrain::save (Iff& iff) const
{
iff.insertForm (TAG_0001);
iff.insertChunk (TAG_DATA);
iff.insertChunkData (m_mapWidthInMeters);
iff.insertChunkData (m_chunkWidthInMeters);
iff.insertChunkData (m_width);
iff.insertChunkData (m_height);
iff.exitChunk (TAG_DATA);
iff.insertChunk (TAG_WMAP);
iff.insertChunkData (m_waterMap, m_width * m_height);
iff.exitChunk (TAG_WMAP);
iff.insertChunk (TAG_SMAP);
iff.insertChunkData (m_slopeMap, m_width * m_height);
iff.exitChunk (TAG_SMAP);
iff.exitForm (TAG_0001);
}
//-------------------------------------------------------------------
float BakedTerrain::getMapWidthInMeters () const
{
return m_mapWidthInMeters;
}
//-------------------------------------------------------------------
float BakedTerrain::getChunkWidthInMeters () const
{
return m_chunkWidthInMeters;
}
//-------------------------------------------------------------------
bool BakedTerrain::getWater (const int chunkX, const int chunkY) const
{
if (!m_waterMap)
return false;
const int x = chunkX + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
const int y = chunkY + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
return getBool (m_waterMap, x, y);
}
//-------------------------------------------------------------------
bool BakedTerrain::getSlope (const int chunkX, const int chunkY) const
{
if (!m_slopeMap)
return false;
const int x = chunkX + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
const int y = chunkY + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
return getBool (m_slopeMap, x, y);
}
//-------------------------------------------------------------------
bool BakedTerrain::getWater (const Vector2d& position) const
{
if (!m_waterMap)
return false;
int x;
int y;
calculateMapXy (position, x, y);
return getBool (m_waterMap, x, y);
}
//-------------------------------------------------------------------
bool BakedTerrain::getSlope (const Vector2d& position) const
{
if (!m_slopeMap)
return false;
int x;
int y;
calculateMapXy (position, x, y);
return getBool (m_slopeMap, x, y);
}
//-------------------------------------------------------------------
bool BakedTerrain::getWater (const Rectangle2d& rectangle) const
{
return getMap (m_waterMap, rectangle);
}
//-------------------------------------------------------------------
bool BakedTerrain::getSlope (const Rectangle2d& rectangle) const
{
return getMap (m_slopeMap, rectangle);
}
//-------------------------------------------------------------------
void BakedTerrain::setMap (const float mapWidthInMeters, const float chunkWidthInMeters)
{
destroy ();
m_mapWidthInMeters = mapWidthInMeters;
m_chunkWidthInMeters = chunkWidthInMeters;
m_width = static_cast<int> (m_mapWidthInMeters / m_chunkWidthInMeters) / 8;
m_height = static_cast<int> (m_mapWidthInMeters / m_chunkWidthInMeters);
const int size = m_width * m_height;
m_waterMap = new uint8 [size];
memset (m_waterMap, 0, size);
m_slopeMap = new uint8 [size];
memset (m_slopeMap, 0, size);
}
//-------------------------------------------------------------------
void BakedTerrain::setWater (int chunkX, int chunkY, bool water)
{
if (!m_waterMap)
return;
const int x = chunkX + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
const int y = chunkY + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
setBool (m_waterMap, x, y, water);
}
//-------------------------------------------------------------------
void BakedTerrain::setSlope (int chunkX, int chunkY, bool slope)
{
if (!m_slopeMap)
return;
const int x = chunkX + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
const int y = chunkY + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
setBool (m_slopeMap, x, y, slope);
}
//===================================================================
// PRIVATE BakedTerrain
//===================================================================
void BakedTerrain::destroy ()
{
delete [] m_waterMap;
m_waterMap = 0;
delete [] m_slopeMap;
m_slopeMap = 0;
}
//-------------------------------------------------------------------
int BakedTerrain::calculateChunkX (const Vector2d& position) const
{
const int chunkX = static_cast<int> ((position.x >= 0.f) ? floorf (position.x / m_chunkWidthInMeters) : ceilf (position.x / m_chunkWidthInMeters));
return (position.x < 0.f) ? chunkX - 1 : chunkX;
}
//-------------------------------------------------------------------
int BakedTerrain::calculateChunkY (const Vector2d& position) const
{
const int chunkY = static_cast<int> ((position.y >= 0.f) ? floorf (position.y / m_chunkWidthInMeters) : ceilf (position.y / m_chunkWidthInMeters));
return (position.y < 0.f) ? chunkY - 1 : chunkY;
}
//-------------------------------------------------------------------
void BakedTerrain::calculateMapXy (const Vector2d& position, int& x, int& y) const
{
x = calculateChunkX (position) + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
y = calculateChunkY (position) + static_cast<int> ((m_mapWidthInMeters / m_chunkWidthInMeters) * 0.5f);
}
//-------------------------------------------------------------------
bool BakedTerrain::getBool (const uint8* const map, const int mapX, const int mapY) const
{
const int index = mapX >> 3;
const int offset = mapX % 8;
if (index < 0 || index >= m_width || mapY < 0 || mapY >= m_height)
return false;
return (map [mapY * m_width + index] & (1 << offset)) != 0;
}
//-------------------------------------------------------------------
bool BakedTerrain::getMap (const uint8* const map, const Rectangle2d& rectangle) const
{
if (!map)
return false;
int x0;
int y0;
calculateMapXy (Vector2d (rectangle.x0, rectangle.y0), x0, y0);
int x1;
int y1;
calculateMapXy (Vector2d (rectangle.x1, rectangle.y1), x1, y1);
if (x0 > x1)
std::swap (x0, x1);
if (y0 > y1)
std::swap (y0, y1);
int x;
int y;
for (y = y0; y <= y1; ++y)
for (x = x0; x <= x1; ++x)
if (getBool (map, x, y))
return true;
return false;
}
//-------------------------------------------------------------------
void BakedTerrain::setBool (uint8* const map, const int mapX, const int mapY, const bool value)
{
const int index = mapX >> 3;
const int offset = mapX % 8;
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, index, m_width);
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE (0, mapY, m_height);
if (value)
map [mapY * m_width + index] |= (1 << offset);
else
map [mapY * m_width + index] &= ~(1 << offset);
}
//-------------------------------------------------------------------
void BakedTerrain::load_0000 (Iff& iff)
{
iff.enterForm (TAG_0000);
iff.exitForm (TAG_0000, true);
}
//-------------------------------------------------------------------
void BakedTerrain::load_0001 (Iff& iff)
{
iff.enterForm (TAG_0001);
iff.enterChunk (TAG_DATA);
m_mapWidthInMeters = iff.read_float ();
m_chunkWidthInMeters = iff.read_float ();
m_width = iff.read_int32 ();
m_height = iff.read_int32 ();
iff.exitChunk (TAG_DATA);
iff.enterChunk (TAG_WMAP);
m_waterMap = iff.readRest_uint8 ();
iff.exitChunk (TAG_WMAP);
iff.enterChunk (TAG_SMAP);
m_slopeMap = iff.readRest_uint8 ();
iff.exitChunk (TAG_SMAP);
iff.exitForm (TAG_0001);
}
//===================================================================
@@ -0,0 +1,79 @@
//===================================================================
//
// BakedTerrain.h
// asommers
//
// copyright 2002, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_BakedTerrain_H
#define INCLUDED_BakedTerrain_H
//===================================================================
class Iff;
class Rectangle2d;
class Vector2d;
//===================================================================
class BakedTerrain
{
friend class TerrainEditorDoc;
public:
BakedTerrain ();
~BakedTerrain ();
void load (Iff& iff);
void save (Iff& iff) const;
float getMapWidthInMeters () const;
float getChunkWidthInMeters () const;
bool getWater (int chunkX, int chunkY) const;
bool getSlope (int chunkX, int chunkY) const;
bool getWater (const Vector2d& position) const;
bool getSlope (const Vector2d& position) const;
bool getWater (const Rectangle2d& rectangle) const;
bool getSlope (const Rectangle2d& rectangle) const;
//-- tool use only
void setMap (float mapWidthInMeters, float chunkWidthInMeters);
void setWater (int chunkX, int chunkY, bool water);
void setSlope (int chunkX, int chunkY, bool slope);
private:
void destroy ();
int calculateChunkX (const Vector2d& position) const;
int calculateChunkY (const Vector2d& position) const;
void calculateMapXy (const Vector2d& position, int& x, int& y) const;
bool getBool (const uint8* map, int mapX, int mapY) const;
bool getMap (const uint8* map, const Rectangle2d& rectangle) const;
void setBool (uint8* map, int mapX, int mapY, bool value);
void load_0000 (Iff& iff);
void load_0001 (Iff& iff);
private:
BakedTerrain (const BakedTerrain&);
BakedTerrain& operator= (const BakedTerrain&);
private:
float m_mapWidthInMeters;
float m_chunkWidthInMeters;
int m_width;
int m_height;
uint8* m_waterMap;
uint8* m_slopeMap;
};
//===================================================================
#endif
@@ -0,0 +1,73 @@
// ======================================================================
//
// BakedTerrainReader.cpp
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/BakedTerrainReader.h"
#include "sharedFile/Iff.h"
#include "sharedUtility/BakedTerrain.h"
// ======================================================================
// BakedTerrainReaderNamespace
// ======================================================================
namespace BakedTerrainReaderNamespace
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tag const TAG_MPTA = TAG (M,P,T,A);
Tag const TAG_PTAT = TAG (P,T,A,T);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BakedTerrain * load (Iff & iff)
{
if (iff.getCurrentName () != TAG_MPTA && iff.getCurrentName () != TAG_PTAT)
return 0;
iff.enterForm ();
iff.enterForm ();
iff.enterChunk ();
iff.exitChunk (true);
iff.enterForm ();
iff.exitForm (true);
BakedTerrain * const bakedTerrain = new BakedTerrain ();
bakedTerrain->load (iff);
iff.exitForm (true);
iff.exitForm (true);
DEBUG_REPORT_LOG (true, ("BakedTerrainReader: loaded terrain for %s\n", iff.getFileName ()));
return bakedTerrain;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
using namespace BakedTerrainReaderNamespace;
// ======================================================================
// STATIC BakedTerrainReader
// ======================================================================
BakedTerrain * BakedTerrainReader::create (char const * const fileName)
{
Iff iff;
if (iff.open (fileName, true))
return load (iff);
return 0;
}
// ======================================================================
@@ -0,0 +1,29 @@
// ======================================================================
//
// BakedTerrainReader.h
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_BakedTerrainReader_H
#define INCLUDED_BakedTerrainReader_H
// ======================================================================
class BakedTerrain;
// ======================================================================
class BakedTerrainReader
{
public:
static BakedTerrain * create (char const * fileName);
};
// ======================================================================
#endif
@@ -0,0 +1,282 @@
// ======================================================================
//
// CachedFileManager.cpp
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/CachedFileManager.h"
#include "sharedDebug/InstallTimer.h"
#include "sharedFile/Iff.h"
#include "sharedFile/TreeFile.h"
#include "sharedFoundation/Clock.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedFoundation/CrcString.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedFoundation/LessPointerComparator.h"
#include "sharedFoundation/Os.h"
#include "sharedFoundation/PersistentCrcString.h"
#include "sharedFoundation/PointerDeleter.h"
#include "sharedFoundation/Production.h"
#include "sharedFoundation/VoidMemberFunction.h"
#include "sharedUtility/ConfigSharedUtility.h"
#include <algorithm>
#include <map>
#include <string>
// ======================================================================
namespace CachedFileManagerNamespace
{
#if PRODUCTION == 0
class CachedFileInfo
{
public:
explicit CachedFileInfo (char const * extension);
~CachedFileInfo ();
CrcString const * getExtension () const;
int getSize () const;
void addFile (int size);
void report () const;
private:
CachedFileInfo ();
CachedFileInfo (CachedFileInfo const &);
CachedFileInfo & operator= (CachedFileInfo const &);
private:
PersistentCrcString const m_extension;
int m_numberOfFiles;
int m_size;
};
typedef std::map<CrcString const *, CachedFileInfo *, LessPointerComparator> ExtensionMap;
ExtensionMap ms_extensionMap;
int ms_totalAllocatedBytes;
#endif
Tag const TAG_CACH = TAG (C,A,C,H);
char * ms_filenames = NULL;
size_t ms_filenamesLength = 0;
size_t ms_filenamesCurrentPos = 0;
unsigned long ms_totalTime;
size_t ms_numberOfFilesLoaded;
std::string ms_cacheFileName;
void remove ();
}
using namespace CachedFileManagerNamespace;
// ======================================================================
#if PRODUCTION == 0
CachedFileInfo::CachedFileInfo (char const * const extension) :
m_extension (extension, false),
m_numberOfFiles (0),
m_size (0)
{
}
// ----------------------------------------------------------------------
CachedFileInfo::~CachedFileInfo ()
{
}
// ----------------------------------------------------------------------
CrcString const * CachedFileInfo::getExtension () const
{
return &m_extension;
}
// ----------------------------------------------------------------------
int CachedFileInfo::getSize () const
{
return m_size;
}
// ----------------------------------------------------------------------
void CachedFileInfo::addFile (int const size)
{
++m_numberOfFiles;
m_size += size;
}
// ----------------------------------------------------------------------
void CachedFileInfo::report () const
{
REPORT_LOG (true, ("| type=%s, count=%5d, size=%9d\n", m_extension.getString (), m_numberOfFiles, m_size));
}
#endif
// ======================================================================
void CachedFileManager::install(bool const allowFileCaching)
{
InstallTimer const installTimer("CachedFileManager::install");
if (!allowFileCaching || ConfigSharedUtility::getDisableFileCaching())
return;
char const * const result = ConfigSharedUtility::getUseCacheFile();
if (result)
{
ms_cacheFileName = result;
Iff iff;
if (iff.open (result, true))
{
iff.enterForm (TAG_CACH);
iff.enterChunk (TAG_0000);
//-- the entire chunk is filled with null terminated strings
ms_filenamesLength = iff.getChunkLengthLeft();
ms_filenames = iff.readRest_char();
iff.exitChunk (TAG_0000);
iff.exitForm (TAG_CACH);
}
}
ExitChain::add (CachedFileManagerNamespace::remove, "CachedFileManagerNamespace::remove");
}
// ----------------------------------------------------------------------
void CachedFileManagerNamespace::remove ()
{
delete[] ms_filenames;
ms_filenames = NULL;
ms_filenamesCurrentPos = 0;
ms_filenamesLength = 0;
#if PRODUCTION == 0
std::for_each (ms_extensionMap.begin (), ms_extensionMap.end (), PointerDeleterPairSecond ());
ms_extensionMap.clear();
#endif
}
// ----------------------------------------------------------------------
void CachedFileManager::preloadSomeAssets ()
{
if (!donePreloading ())
{
unsigned long const startTime = Clock::timeMs ();
#if PRODUCTION == 0
unsigned long const bytesBefore = MemoryManager::getCurrentNumberOfBytesAllocated();
#endif
//-- preloading occurs in one second slices
while (ms_filenamesCurrentPos < ms_filenamesLength && Clock::timeMs () - startTime < 1000)
{
char const * const fileName = ms_filenames + ms_filenamesCurrentPos;
if (TreeFile::exists(fileName))
{
#if PRODUCTION == 0
int const fileSize = TreeFile::cacheFile (fileName);
//-- record cached file information per extension
char const * const possibleExtension = strrchr (fileName, '.');
if (possibleExtension)
{
ConstCharCrcString const extension (possibleExtension + 1);
ExtensionMap::iterator iter = ms_extensionMap.find (&extension);
if (iter == ms_extensionMap.end ())
{
CachedFileInfo * const info = new CachedFileInfo (extension.getString ());
std::pair<ExtensionMap::iterator, bool> result = ms_extensionMap.insert (ExtensionMap::value_type (info->getExtension (), info));
DEBUG_FATAL (!result.second, ("insert failed"));
iter = result.first;
}
iter->second->addFile (fileSize);
}
++ms_numberOfFilesLoaded;
#else
IGNORE_RETURN(TreeFile::cacheFile (fileName));
#endif
}
ms_filenamesCurrentPos += strlen(fileName) + 1;
}
#if PRODUCTION == 0
unsigned long const stopTime = Clock::timeMs ();
ms_totalTime += stopTime - startTime;
ms_totalAllocatedBytes += MemoryManager::getCurrentNumberOfBytesAllocated() - bytesBefore;
#endif
if (donePreloading ())
{
#if PRODUCTION == 0
REPORT_LOG (true, ("CachedFileManager [%s]: Caching took [%.2f] seconds for [%d] files and increased memory usage by [%.2f] MB.\n", ms_cacheFileName.c_str (), static_cast<float> (ms_totalTime) / 1000.f, ms_numberOfFilesLoaded, static_cast<float> (ms_totalAllocatedBytes) / (1024.0f * 1024.0f)));
int size = 0;
while (!ms_extensionMap.empty ())
{
ExtensionMap::iterator iter = ms_extensionMap.begin ();
iter->second->report ();
size += iter->second->getSize ();
delete iter->second;
ms_extensionMap.erase (iter);
}
std::for_each(ms_extensionMap.begin (), ms_extensionMap.end (), PointerDeleterPairSecond ());
ms_extensionMap.clear();
REPORT_LOG (true, ("+ Total cached data size = %.2f MB.\n", static_cast<float> (size) / (1024.0f * 1024.0f)));
#endif
delete[] ms_filenames;
ms_filenames = NULL;
ms_filenamesCurrentPos = 0;
ms_filenamesLength = 0;
}
}
}
// ----------------------------------------------------------------------
bool CachedFileManager::donePreloading ()
{
return ms_filenames == NULL || (ms_filenamesCurrentPos >= ms_filenamesLength);
}
// ----------------------------------------------------------------------
int CachedFileManager::getLoadingPercent ()
{
if (ms_filenamesLength == 0)
return 100;
return (ms_filenamesCurrentPos * 100) / ms_filenamesLength;
}
// ======================================================================
@@ -0,0 +1,28 @@
// ======================================================================
//
// CachedFileManager.h
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_CachedFileManager_H
#define INCLUDED_CachedFileManager_H
// ======================================================================
class CachedFileManager
{
public:
static void install(bool allowFileCaching);
static void preloadSomeAssets ();
static bool donePreloading ();
static int getLoadingPercent ();
};
// ======================================================================
#endif
@@ -0,0 +1,109 @@
// ======================================================================
//
// Callback.cpp
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/Callback.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedFoundation/MemoryBlockManager.h"
#include "sharedUtility/CallbackReceiver.h"
#include <algorithm>
// ======================================================================
MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITH_INSTALL (Callback, true, 0, 0, 0);
// ======================================================================
Callback::Callback()
: m_referenceCount(0),
m_receivers(),
m_inPerformCallback (false)
{
}
// ----------------------------------------------------------------------
Callback::~Callback()
{
DEBUG_FATAL(m_referenceCount, ("Callback deleted with non-zero reference count"));
m_receivers.clear ();
}
// ----------------------------------------------------------------------
void Callback::attachReceiver(CallbackReceiver &receiver)
{
DEBUG_FATAL (m_inPerformCallback, ("Callback cannot attach receivers while receiving callbacks"));
//-- pre-reserve the space to prevent the vector from agressively allocating more space
m_receivers.reserve (m_receivers.size () + 1);
m_receivers.push_back (&receiver);
}
// ----------------------------------------------------------------------
void Callback::detachReceiver(CallbackReceiver &receiver)
{
DEBUG_FATAL (m_inPerformCallback, ("Callback cannot detach receivers while receiving callbacks"));
const CallbackReceiverVector::iterator remove_begin = std::remove (m_receivers.begin (), m_receivers.end (), &receiver);
if (remove_begin == m_receivers.end ())
{
DEBUG_FATAL (true, ("Callback attempted to detach unattached receeiver."));
return;
}
m_receivers.erase (remove_begin, m_receivers.end ());
}
// ----------------------------------------------------------------------
bool Callback::hasAnyReceivers() const
{
return !m_receivers.empty ();
}
// ----------------------------------------------------------------------
void Callback::performCallback()
{
m_inPerformCallback = true;
const CallbackReceiverVector::const_iterator end = m_receivers.end ();
for (CallbackReceiverVector::const_iterator it = m_receivers.begin (); it != end; ++it)
{
CallbackReceiver * const receiver = *it;
NOT_NULL (receiver);
if (receiver)
receiver->performCallback();
}
m_inPerformCallback = false;
}
// ----------------------------------------------------------------------
void Callback::fetch()
{
++m_referenceCount;
// sanity check
DEBUG_FATAL(m_referenceCount < 1, ("invalid reference count %d after fetch()", m_referenceCount));
}
// ----------------------------------------------------------------------
void Callback::release()
{
--m_referenceCount;
if (m_referenceCount < 1)
{
DEBUG_FATAL(m_referenceCount < 0, ("bad reference count handling [%d]", m_referenceCount));
delete this;
}
}
// ======================================================================
@@ -0,0 +1,61 @@
// ======================================================================
//
// Callback.h
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_Callback_H
#define INCLUDED_Callback_H
// ======================================================================
class CallbackReceiver;
class MemoryBlockManager;
#include <vector>
#include "sharedFoundation/MemoryBlockManagerMacros.h"
// ======================================================================
class Callback
{
public:
MEMORY_BLOCK_MANAGER_INTERFACE_WITH_INSTALL;
public:
Callback();
void attachReceiver(CallbackReceiver &receiver);
void detachReceiver(CallbackReceiver &receiver);
bool hasAnyReceivers() const;
void performCallback();
void fetch();
void release();
private:
~Callback();
private:
typedef stdvector<CallbackReceiver *>::fwd CallbackReceiverVector;
int m_referenceCount;
CallbackReceiverVector m_receivers;
bool m_inPerformCallback;
private:
// disabled
Callback(const Callback&);
Callback &operator =(const Callback&);
};
// ======================================================================
#endif
@@ -0,0 +1,28 @@
// ======================================================================
//
// CallbackReceiver.h
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CallbackReceiver_H
#define INCLUDED_CallbackReceiver_H
// ======================================================================
class CallbackReceiver
{
public:
virtual void performCallback() = 0;
protected:
CallbackReceiver() {}
virtual ~CallbackReceiver() {}
};
// ======================================================================
#endif
@@ -0,0 +1,69 @@
// ======================================================================
//
// ConfigSharedUtility.cpp
// copyright 2004 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/ConfigSharedUtility.h"
#include "sharedFoundation/ConfigFile.h"
// ======================================================================
#define KEY_BOOL(a,b) (ms_ ## a = ConfigFile::getKeyBool("SharedUtility", #a, (b)))
#define KEY_INT(a,b) (ms_ ## a = ConfigFile::getKeyInt("SharedUtility", #a, (b)))
#define KEY_STRING(a,b) (ms_ ## a = ConfigFile::getKeyString("SharedUtility", #a, (b)))
// ======================================================================
namespace ConfigSharedUtilityNamespace
{
bool ms_disableFileCaching;
char const * ms_useCacheFile;
int ms_chunkSize;
bool ms_logOptionManager;
}
using namespace ConfigSharedUtilityNamespace;
// ======================================================================
void ConfigSharedUtility::install()
{
KEY_BOOL(disableFileCaching, false);
KEY_STRING(useCacheFile, "");
KEY_INT(chunkSize, 32);
KEY_BOOL(logOptionManager, false);
}
// ----------------------------------------------------------------------
bool ConfigSharedUtility::getDisableFileCaching()
{
return ms_disableFileCaching;
}
// ----------------------------------------------------------------------
char const * ConfigSharedUtility::getUseCacheFile()
{
return ms_useCacheFile;
}
// ----------------------------------------------------------------------
int ConfigSharedUtility::getChunkSize()
{
return ms_chunkSize;
}
// ----------------------------------------------------------------------
bool ConfigSharedUtility::getLogOptionManager()
{
return ms_logOptionManager;
}
// ======================================================================
@@ -0,0 +1,28 @@
// ======================================================================
//
// ConfigSharedUtility.h
// Copyright 2004, Sony Online Entertainment Inc.
// All Rights Reserved.
//
// ======================================================================
#ifndef INCLUDED_ConfigSharedUtility_H
#define INCLUDED_ConfigSharedUtility_H
// ======================================================================
class ConfigSharedUtility
{
public:
static void install();
static bool getDisableFileCaching();
static char const * getUseCacheFile();
static int getChunkSize();
static bool getLogOptionManager();
};
// ======================================================================
#endif
@@ -0,0 +1,128 @@
// ======================================================================
//
// CurrentUserOptionManager.cpp
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/CurrentUserOptionManager.h"
#include "sharedDebug/DebugFlags.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedUtility/OptionManager.h"
#include <string>
// ======================================================================
// CurrentUserOptionManagerNamespace
// ======================================================================
namespace CurrentUserOptionManagerNamespace
{
bool ms_installed;
OptionManager * ms_optionManager;
std::string ms_userName;
bool s_verbose = false;
}
using namespace CurrentUserOptionManagerNamespace;
// ======================================================================
// STATIC PUBLIC CurrentUserOptionManager
// ======================================================================
void CurrentUserOptionManager::install ()
{
DEBUG_FATAL (ms_installed, ("CurrentUserOptionManager::install: already installed"));
ms_installed = true;
ms_optionManager = new OptionManager;
ExitChain::add (remove, "CurrentUserOptionManager::remove");
DebugFlags::registerFlag(s_verbose, "sharedUtility/CurrentUserOptionManager", "verbose");
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::remove ()
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::remove: not installed"));
ms_installed = false;
delete ms_optionManager;
ms_optionManager = 0;
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::load (char const * const userName)
{
if (userName && *userName)
{
ms_userName = userName;
DEBUG_REPORT_LOG (s_verbose, ("CurrentUserOptionManager::load: user name set to %s, loading %s\n", userName, ms_userName.c_str ()));
ms_optionManager->load (ms_userName.c_str ());
}
else
DEBUG_WARNING (true, ("CurrentUserOptionManager::load: userName is null"));
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::save ()
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::save: not installed"));
if (!ms_userName.empty ())
ms_optionManager->save (ms_userName.c_str ());
else
DEBUG_REPORT_LOG (s_verbose, ("CurrentUserOptionManager::save: userName is null\n"));
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::registerOption (bool & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::registerOption (float & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::registerOption (int & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::registerOption (std::string & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void CurrentUserOptionManager::registerOption (Unicode::String & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("CurrentUserOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ======================================================================
@@ -0,0 +1,41 @@
// ======================================================================
//
// CurrentUserOptionManager.h
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_CurrentUserOptionManager_H
#define INCLUDED_CurrentUserOptionManager_H
// ======================================================================
class CurrentUserOptionManager
{
public:
static void install ();
static void remove ();
static void load (char const * userName);
static void save ();
static void registerOption (bool & variable, char const * section, char const * name, const int version = 0);
static void registerOption (float & variable, char const * section, char const * name, const int version = 0);
static void registerOption (int & variable, char const * section, char const * name, const int version = 0);
static void registerOption (std::string & variable, char const * section, char const * name, const int version = 0);
static void registerOption (Unicode::String & variable, char const * section, char const * name, const int version = 0);
private:
CurrentUserOptionManager ();
~CurrentUserOptionManager ();
CurrentUserOptionManager (CurrentUserOptionManager const &);
CurrentUserOptionManager & operator= (CurrentUserOptionManager const &);
};
// ======================================================================
#endif
@@ -0,0 +1,763 @@
// ======================================================================
//
// DataTable.cpp
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/DataTable.h"
#include "sharedFile/Iff.h"
#include "sharedUtility/DataTableCell.h"
#include <map>
#include <hash_map>
//----------------------------------------------------------------------------
const Tag DataTable::m_dataTableIffId = TAG(D,T,I,I);
//----------------------------------------------------------------------------
DataTable::DataTable() :
m_numRows(0),
m_numCols(0),
m_cells(0),
m_columns(),
m_index(),
m_types(),
m_columnIndexMap(new ColumnIndexMap(17)),
m_name()
{
}
//----------------------------------------------------------------------------
DataTable::~DataTable()
{
std::vector<void *>::iterator k = m_index.begin();
int count = 0;
for (; k != m_index.end(); ++k, ++count)
{
DataTableColumnType::DataType dt = m_types[static_cast<size_t>(count)]->getBasicType();
switch (dt)
{
case DataTableColumnType::DT_Int:
{
if (*k)
{
delete static_cast<std::multimap<int, int> *>(*k);
*k = NULL;
}
}
break;
case DataTableColumnType::DT_Float:
{
if (*k)
{
delete static_cast<std::multimap<float, int> *>(*k);
*k = NULL;
}
}
break;
case DataTableColumnType::DT_String:
{
if (*k)
{
delete static_cast<std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > *>(*k);
*k = NULL;
}
}
break;
case DataTableColumnType::DT_HashString:
case DataTableColumnType::DT_Enum:
case DataTableColumnType::DT_Bool:
case DataTableColumnType::DT_BitVector:
case DataTableColumnType::DT_Unknown:
case DataTableColumnType::DT_Comment:
case DataTableColumnType::DT_PackedObjVars:
default:
{
WARNING_STRICT_FATAL((*k) != NULL, ("Bad column Index %d. Unsupported datatype. This may leak memory.", count));
}
break;
}
}
if (m_cells)
{
for (int row=0;row<m_numRows;++row)
{
const DataTableCell *rowCells = m_cells + row * m_numCols;
for (int col=0;col<m_numCols;++col)
{
const DataTableCell &cell = rowCells[col];
cell.~DataTableCell();
}
}
free((void *)m_cells);
m_cells=0;
}
DataTableColumnTypeVector::iterator l = m_types.begin();
while(l != m_types.end())
{
delete *l++;
}
delete m_columnIndexMap;
m_columnIndexMap = NULL;
}
//----------------------------------------------------------------------------
bool DataTable::doesColumnExist(const std::string & column) const
{
DEBUG_FATAL(m_columnIndexMap->empty(), ("DataTable(%x) [%s]: Column index map is empty.\n", this, m_name.c_str()));
return m_columnIndexMap->find(column) != m_columnIndexMap->end();
}
//----------------------------------------------------------------------------
int DataTable::findColumnNumber(const std::string & column) const
{
DEBUG_FATAL(m_columnIndexMap->empty(), ("DataTable(%x) [%s]: Column index map is empty.\n", this, m_name.c_str()));
int count = -1;
ColumnIndexMap::const_iterator const it = m_columnIndexMap->find(column);
if (it != m_columnIndexMap->end())
{
count = it->second;
}
return count;
}
//----------------------------------------------------------------------------
const std::string & DataTable::getColumnName(int column) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getColumnName(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
return m_columns[static_cast<size_t>(column)];
}
//----------------------------------------------------------------------------
DataTableColumnType DataTable::getDataType(const std::string & type)
{
return DataTableColumnType(type);
}
//----------------------------------------------------------------------------
DataTableColumnType const &DataTable::getDataTypeForColumn(const std::string& column) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable [%s] getDataTypeForColumn(): Column name [%s] is invalid\n", m_name.c_str(), column.c_str()));
return getDataTypeForColumn(columnIndex);
}
//----------------------------------------------------------------------------
DataTableColumnType const &DataTable::getDataTypeForColumn(int column) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getDataTypeForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
return *m_types[static_cast<size_t>(column)];
}
//----------------------------------------------------------------------------
int DataTable::getIntValue(const std::string & column, int row) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable [%s] getIntValue(): Column name [%s] is invalid\n", m_name.c_str(), column.c_str()));
return getIntValue(columnIndex, row);
}
//----------------------------------------------------------------------------
int DataTable::getIntValue(int column, int row) const
{
DEBUG_FATAL(row < 0 || row >= getNumRows(), ("DataTable [%s] getIntValue(): Invalid row number [%d]. Rows=[%d]\n", m_name.c_str(), row, getNumRows()));
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getIntValue(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
// we can return the value of an int column or the crc value of a string column
if (m_types[static_cast<size_t>(column)]->getBasicType() == DataTableColumnType::DT_Int)
{
const DataTableCell *cell = getDataTableCell(column, row);
DEBUG_FATAL(cell->getType()!=DataTableCell::CT_int, ("Could not convert row %d column %d to int value", row, column));
return cell->getIntValue();
}
else if (m_types[static_cast<size_t>(column)]->getBasicType() == DataTableColumnType::DT_String)
{
const DataTableCell *cell = getDataTableCell(column, row);
DEBUG_FATAL(cell->getType()!=DataTableCell::CT_string, ("Could not convert row %d column %d to string value", row, column));
return cell->getStringValueCrc();
}
DEBUG_FATAL(true, ("DataTable [%s] getIntValue(): Wrong data type [%d] for col [%d].\n", m_name.c_str(), m_types[static_cast<size_t>(column)]->getBasicType(), column));
return 0;
}
//----------------------------------------------------------------------------
int DataTable::getIntDefaultForColumn(const std::string & column) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable [%s] getIntDefaultForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), columnIndex, getNumColumns()));
return getIntDefaultForColumn(columnIndex);
}
//----------------------------------------------------------------------------
int DataTable::getIntDefaultForColumn(int column) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getIntDefaultForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
DEBUG_FATAL(m_types[static_cast<size_t>(column)]->getBasicType() != DataTableColumnType::DT_Int, ("Wrong data type for column %d.", column));
std::string value;
IGNORE_RETURN( getDataTypeForColumn(column).mangleValue(value) );
return atoi(value.c_str());
}
//----------------------------------------------------------------------------
float DataTable::getFloatValue(const std::string & column, int row) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
return getFloatValue(columnIndex, row);
}
//----------------------------------------------------------------------------
float DataTable::getFloatValue(int column, int row) const
{
DEBUG_FATAL(row < 0 || row >= getNumRows(), ("Row is invalid."));
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getFloatValue(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
DEBUG_FATAL(m_types[static_cast<size_t>(column)]->getBasicType() != DataTableColumnType::DT_Float, ("Wrong data type for column %d.", column));
const DataTableCell *cell = getDataTableCell(column, row);
DEBUG_FATAL(cell->getType()!=DataTableCell::CT_float, ("Could not convert row %d column %d to float value", row, column));
return cell->getFloatValue();
}
//----------------------------------------------------------------------------
float DataTable::getFloatDefaultForColumn(const std::string & column) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
return getFloatDefaultForColumn(columnIndex);
}
//----------------------------------------------------------------------------
float DataTable::getFloatDefaultForColumn(int column) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getFloatDefaultForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
DEBUG_FATAL(m_types[static_cast<size_t>(column)]->getBasicType() != DataTableColumnType::DT_Float, ("Wrong data type for column %d.", column));
std::string value;
IGNORE_RETURN ( getDataTypeForColumn(column).mangleValue(value) );
return static_cast<float>(atof(value.c_str()));
}
//----------------------------------------------------------------------------
const char *DataTable::getStringValue(const std::string & column, int row) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
return getStringValue(columnIndex, row);
}
//----------------------------------------------------------------------------
const char *DataTable::getStringValue(int column, int row) const
{
DEBUG_FATAL(row < 0 || row >= getNumRows(), ("Row [%d] is invalid.", row));
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("Column [%d] is invalid.", column));
DEBUG_FATAL(m_types[static_cast<size_t>(column)]->getBasicType() != DataTableColumnType::DT_String, ("Wrong data type for column %s (%d). Current data type is %s", getColumnName(column).c_str(), column, getDataTypeForColumn(column).getTypeSpecString().c_str()));
const DataTableCell * const cell = getDataTableCell(column, row);
DEBUG_FATAL(cell->getType()!=DataTableCell::CT_string, ("Could not convert row %d column %d to string value", row, column));
return cell->getStringValue();
}
//----------------------------------------------------------------------------
std::string DataTable::getStringDefaultForColumn(const std::string & column) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
return getStringDefaultForColumn(columnIndex);
}
//----------------------------------------------------------------------------
std::string DataTable::getStringDefaultForColumn(int column) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] getStringDefaultForColumn(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
DEBUG_FATAL(m_types[static_cast<size_t>(column)]->getBasicType() != DataTableColumnType::DT_String, ("Wrong data type for column %d.", column));
std::string value;
IGNORE_RETURN( getDataTypeForColumn(column).mangleValue(value) );
return value;
}
//----------------------------------------------------------------------------
void DataTable::getIntColumn(const std::string& column, std::vector<int>& returnVector) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
getIntColumn(columnIndex, returnVector);
}
//----------------------------------------------------------------------------
void DataTable::getIntColumn(const std::string& column, std::vector<long>& returnVector) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
getIntColumn(columnIndex, returnVector);
}
//----------------------------------------------------------------------------
void DataTable::getFloatColumn(const std::string& column, std::vector<float>& returnVector) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
getFloatColumn(columnIndex, returnVector);
}
//----------------------------------------------------------------------------
void DataTable::getStringColumn(const std::string& column, std::vector<const char *>& returnVector) const
{
int const columnIndex = findColumnNumber(column);
DEBUG_FATAL(columnIndex < 0 || columnIndex >= getNumColumns(), ("DataTable Column [%s] is invalid", column.c_str()));
getStringColumn(columnIndex, returnVector);
}
//----------------------------------------------------------------------------
void DataTable::getIntColumn(int column, std::vector<int>& returnVector) const
{
returnVector.clear();
for (int i = 0; i < getNumRows(); ++i)
{
returnVector.push_back(getIntValue(column, i));
}
}
//----------------------------------------------------------------------------
void DataTable::getIntColumn(int column, std::vector<long>& returnVector) const
{
returnVector.clear();
for (int i = 0; i < getNumRows(); ++i)
{
returnVector.push_back(getIntValue(column, i));
}
}
//----------------------------------------------------------------------------
void DataTable::getFloatColumn(int column, std::vector<float>& returnVector) const
{
returnVector.clear();
for (int i = 0; i < getNumRows(); ++i)
{
returnVector.push_back(getFloatValue(column, i));
}
}
//----------------------------------------------------------------------------
void DataTable::getStringColumn(int column, std::vector<const char *>& returnVector) const
{
returnVector.clear();
for (int i = 0; i < getNumRows(); ++i)
{
returnVector.push_back(getStringValue(column, i));
}
}
//----------------------------------------------------------------------------
void DataTable::_readCell(Iff & iff, int column, int row)
{
DataTableCell *cell = const_cast<DataTableCell *>(getDataTableCell(column, row));
const DataTableColumnType &typeCol = *m_types[static_cast<size_t>(column)];
switch (typeCol.getBasicType())
{
case DataTableColumnType::DT_Int:
{
int tmp = iff.read_int32();
new (cell) DataTableCell(tmp);
break;
}
case DataTableColumnType::DT_Float:
{
float tmp = iff.read_float();
new (cell) DataTableCell(tmp);
break;
}
case DataTableColumnType::DT_String:
{
const int maxLen = 16384;
char buffer[maxLen];
buffer[0]=0;
iff.read_string(buffer, maxLen-1);
buffer[maxLen-1]=0;
new (cell) DataTableCell(buffer);
break;
}
case DataTableColumnType::DT_Unknown:
case DataTableColumnType::DT_HashString:
case DataTableColumnType::DT_Enum:
case DataTableColumnType::DT_Bool:
case DataTableColumnType::DT_BitVector:
case DataTableColumnType::DT_Comment:
case DataTableColumnType::DT_PackedObjVars:
default:
DEBUG_FATAL(true, ("bad case"));
break;
}
}
//----------------------------------------------------------------------------
void DataTable::load(Iff & iff)
{
IGNORE_RETURN ( iff.enterForm(m_dataTableIffId, false) );
const Tag version = iff.getCurrentName();
if (version == TAG_0000)
load_0000(iff);
else if (version == TAG_0001)
load_0001(iff);
else
{
char buffer[5];
ConvertTagToString(version, buffer);
FATAL(true, ("unknown DataTable file format [%s]", buffer));
}
iff.exitForm(m_dataTableIffId, false);
int count = getNumColumns();
for (int i = 0; i < count; ++i)
{
//initialize the table index used for searching.
m_index.push_back(NULL);
}
buildColumnIndexMap();
if (NULL != iff.getFileName())
m_name = iff.getFileName();
else
m_name.clear();
}
//----------------------------------------------------------------------------
void DataTable::load_0000(Iff & iff)
{
IGNORE_RETURN ( iff.enterForm(TAG_0000, false) );
//load columns
iff.enterChunk(TAG(C,O,L,S));
m_numCols = iff.read_int32();
int i = 0;
m_columns.reserve(m_numCols);
std::string tmpString;
for (i = 0; i < m_numCols; ++i)
{
iff.read_string(tmpString);
m_columns.push_back(tmpString);
tmpString.clear();
}
iff.exitChunk(TAG(C,O,L,S));
//load type info
iff.enterChunk(TAG(T,Y,P,E));
for (i = 0; i < m_numCols; ++i)
{
DataTableColumnType::DataType dt = static_cast<DataTableColumnType::DataType>(iff.read_int32());
// version 0000 has only Int, Float, String, and no other format information
switch (dt)
{
case DataTableColumnType::DT_Int:
{
m_types.push_back(new DataTableColumnType("i"));
}
break;
case DataTableColumnType::DT_Float:
{
m_types.push_back(new DataTableColumnType("f"));
}
break;
case DataTableColumnType::DT_String:
{
m_types.push_back(new DataTableColumnType("s"));
}
break;
case DataTableColumnType::DT_Unknown:
case DataTableColumnType::DT_HashString:
case DataTableColumnType::DT_Enum:
case DataTableColumnType::DT_Bool:
case DataTableColumnType::DT_BitVector:
case DataTableColumnType::DT_Comment:
case DataTableColumnType::DT_PackedObjVars:
default:
{
FATAL(true, ("unknown column type loaded from version 0000"));
}
break;
}
}
iff.exitChunk(TAG(T,Y,P,E));
//load rows
iff.enterChunk(TAG(R,O,W,S));
m_numRows = iff.read_int32();
const size_t cellSize = m_numRows * m_numCols * sizeof(DataTableCell);
void *cellMemory = malloc(cellSize);
m_cells = (DataTableCell *)cellMemory;
for (i = 0; i < m_numRows; ++i)
{
for (int j = 0; j < m_numCols; ++j)
{
_readCell(iff, j, i);
}
}
iff.exitChunk(TAG(R,O,W,S));
iff.exitForm(TAG_0000, false);
}
//----------------------------------------------------------------------------
void DataTable::load_0001(Iff & iff)
{
IGNORE_RETURN( iff.enterForm(TAG_0001, false) );
//load columns
iff.enterChunk(TAG(C,O,L,S));
m_numCols = iff.read_int32();
int i = 0;
m_columns.reserve(m_numCols);
std::string tmpString;
for (i = 0; i < m_numCols; ++i)
{
iff.read_string(tmpString);
m_columns.push_back(tmpString);
tmpString.clear();
}
iff.exitChunk(TAG(C,O,L,S));
//load type info
iff.enterChunk(TAG(T,Y,P,E));
for (i = 0; i < m_numCols; ++i)
{
// version 0001 has a format string for the type
m_types.push_back(new DataTableColumnType(iff.read_stdstring()));
}
iff.exitChunk(TAG(T,Y,P,E));
//load rows
iff.enterChunk(TAG(R,O,W,S));
m_numRows = iff.read_int32();
const size_t cellSize = m_numRows * m_numCols * sizeof(DataTableCell);
void *cellMemory = malloc(cellSize);
m_cells = (DataTableCell *)cellMemory;
for (i = 0; i < m_numRows; ++i)
{
for (int j = 0; j < m_numCols; ++j)
{
_readCell(iff, j, i);
}
}
iff.exitChunk(TAG(R,O,W,S));
iff.exitForm(TAG_0001, false);
}
// ----------------------------------------------------------------------
int DataTable::searchColumnString( int column, const std::string & searchValue ) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] searchColumnString(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
int retval = -1;
void * voidIndex = m_index[ static_cast<size_t>(column) ];
if (!voidIndex)
{
std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > * indexPair = new std::pair<std::multimap<const std::string, int>, std::multimap<int, int> >;
NOT_NULL(indexPair);
m_index[static_cast<size_t>(column)] = static_cast<void *>(indexPair);
//no index has been built yet for this column
int rowCount = getNumRows();
for (int i = 0; i < rowCount; ++i)
{
const std::string & valueString = getStringValue(column,i);
IGNORE_RETURN ( indexPair->first.insert(std::pair<const std::string, int>(valueString, i)) );
int valueCrc = getIntValue(column,i);
IGNORE_RETURN ( indexPair->second.insert(std::pair<int, int>(valueCrc, i)) );
if (retval == -1 && valueString == searchValue)
retval = i;
}
}
else
{
std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > * indexPair = static_cast<std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > *>(voidIndex);
std::multimap<const std::string, int>::iterator iter = indexPair->first.find(searchValue);
if (iter != indexPair->first.end())
retval = iter->second;
}
return retval;
}
// ----------
int DataTable::searchColumnFloat( int column, float searchValue ) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] searchColumnFloat(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
int retval = -1;
void * voidIndex = m_index[ static_cast<size_t>(column) ];
if (!voidIndex)
{
std::multimap<float, int> * index = new std::multimap<float, int>;
NOT_NULL(index);
m_index[static_cast<size_t>(column)] = static_cast<void *>(index);
//no index has been built yet for this column
for (int i = 0; i < getNumRows(); ++i)
{
float rowValue = getFloatValue(column,i);
IGNORE_RETURN ( index->insert(std::pair<float, int>(rowValue, i)) );
if (retval == -1 && rowValue == searchValue) //lint !e777 //ok to compare floats
retval = i;
}
}
else
{
std::multimap<float, int> * index = static_cast<std::multimap<float, int> *>(voidIndex);
std::multimap<float, int>::iterator iter = index->find(searchValue);
if (iter != index->end())
retval = iter->second;
}
return retval;
}
// ----------
int DataTable::searchColumnInt( int column, int searchValue ) const
{
DEBUG_FATAL(column < 0 || column >= getNumColumns(), ("DataTable [%s] searchColumnInt(): Invalid col number [%d]. Cols=[%d]\n", m_name.c_str(), column, getNumColumns()));
int retval = -1;
DataTableColumnType::DataType columnType = m_types[static_cast<size_t>(column)]->getBasicType();
void * voidIndex = m_index[ static_cast<size_t>(column) ];
if (!voidIndex)
{
if (columnType == DataTableColumnType::DT_Int)
{
std::multimap<int, int> * index = new std::multimap<int, int>;
NOT_NULL(index);
m_index[static_cast<size_t>(column)] = static_cast<void *>(index);
//no index has been built yet for this column
int rowCount = getNumRows();
for (int i = 0; i < rowCount; ++i)
{
int rowValue = getIntValue(column,i);
IGNORE_RETURN ( index->insert(std::pair<int, int>(rowValue, i)) );
if (retval == -1 && rowValue == searchValue)
retval = i;
}
}
else if (columnType == DataTableColumnType::DT_String)
{
std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > * indexPair = new std::pair<std::multimap<const std::string, int>, std::multimap<int, int> >;
NOT_NULL(indexPair);
m_index[static_cast<size_t>(column)] = static_cast<void *>(indexPair);
//no index has been built yet for this column
int rowCount = getNumRows();
for (int i = 0; i < rowCount; ++i)
{
const std::string & valueString = getStringValue(column,i);
IGNORE_RETURN ( indexPair->first.insert(std::pair<const std::string, int>(valueString, i)) );
int valueCrc = getIntValue(column,i);
IGNORE_RETURN ( indexPair->second.insert(std::pair<int, int>(valueCrc, i)) );
if (retval == -1 && valueCrc == searchValue)
retval = i;
}
}
}
else
{
if (columnType == DataTableColumnType::DT_Int)
{
std::multimap<int, int> * index = static_cast<std::multimap<int, int> *>(voidIndex);
std::multimap<int, int>::iterator iter = index->find(searchValue);
if (iter != index->end())
retval = iter->second;
}
else if (columnType == DataTableColumnType::DT_String)
{
std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > * indexPair = static_cast<std::pair<std::multimap<const std::string, int>, std::multimap<int, int> > *>(voidIndex);
std::multimap<int, int>::iterator iter = indexPair->second.find(searchValue);
if (iter != indexPair->second.end())
retval = iter->second;
}
}
return retval;
}
// ----------
void DataTable::buildColumnIndexMap()
{
std::vector<std::string>::const_iterator i = m_columns.begin();
for (int columnIndex = 0; i != m_columns.end(); ++i, ++columnIndex)
{
(*m_columnIndexMap)[*i] = columnIndex;
}
}
//----------------------------------------------------------------------------
@@ -0,0 +1,127 @@
// ======================================================================
//
// DataTable.h
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_DataTable_H
#define INCLUDED_DataTable_H
#include "sharedFoundation/Tag.h"
#include "DataTableCell.h"
#include "DataTableColumnType.h"
#include <string>
#include <vector>
class Iff;
class DataTable
{
public:
DataTable();
virtual ~DataTable();
bool doesColumnExist(const std::string &) const;
const std::string & getColumnName(int column) const;
int findColumnNumber(const std::string & column) const;
DataTableColumnType const &getDataTypeForColumn(const std::string& column) const;
DataTableColumnType const &getDataTypeForColumn(int column) const;
int getIntValue(const std::string & column, int row) const;
int getIntValue(int column, int row) const;
int getIntDefaultForColumn(const std::string & column) const;
int getIntDefaultForColumn(int column) const;
float getFloatValue(const std::string & column, int row) const;
float getFloatValue(int column, int row) const;
float getFloatDefaultForColumn(const std::string & column) const;
float getFloatDefaultForColumn(int column) const;
const char * getStringValue(const std::string & column, int row) const;
const char * getStringValue(int column, int row) const;
std::string getStringDefaultForColumn(const std::string & column) const;
std::string getStringDefaultForColumn(int column) const;
void getIntColumn(const std::string& column, std::vector<int>& returnVector) const;
void getIntColumn(const std::string& column, std::vector<long>& returnVector) const;
void getFloatColumn(const std::string& column, std::vector<float>& returnVector) const;
void getStringColumn(const std::string& column, std::vector<const char *>& returnVector) const;
void getIntColumn(int column, std::vector<int>& returnVector) const;
void getIntColumn(int column, std::vector<long>& returnVector) const;
void getFloatColumn(int column, std::vector<float>& returnVector) const;
void getStringColumn(int column, std::vector<const char *>& returnVector) const;
int getNumColumns() const;
int getNumRows() const;
void load(Iff &);
// Search a column of the table for a given value and return the index of the first
// matching row. Warning - this is a linear search, so it can be slow.
int searchColumnString(int column, const std::string & searchValue) const;
int searchColumnFloat(int column, float searchValue) const;
int searchColumnInt(int column, int searchValue) const;
std::string const & getName() const;
static Tag getDataTableIffId() { return m_dataTableIffId; }
protected:
const std::vector<std::string> &_columns() const { return m_columns; }
private:
const DataTableCell * getDataTableCell(int column, int row) const;
void _readCell(Iff & iff, int column, int row);
static DataTableColumnType getDataType(const std::string &type);
void load_0000(Iff &);
void load_0001(Iff &);
void buildColumnIndexMap();
typedef std::vector<const DataTableColumnType *> DataTableColumnTypeVector;
typedef stdhash_map<std::string /*column name*/, int /*column index*/>::fwd ColumnIndexMap;
int m_numRows;
int m_numCols;
DataTableCell const * m_cells;
std::vector<std::string> m_columns;
mutable std::vector<void *> m_index;
DataTableColumnTypeVector m_types;
ColumnIndexMap * m_columnIndexMap;
std::string m_name;
static const Tag m_dataTableIffId;
private:
DataTable(DataTable const &);
DataTable & operator=(DataTable const &);
};
inline int DataTable::getNumColumns() const
{
return static_cast<int>(m_columns.size());
}
inline int DataTable::getNumRows() const
{
return m_numRows;
}
inline const DataTableCell * DataTable::getDataTableCell(int column, int row) const
{
return m_cells + (row * m_numCols + column);
}
//----------------------------------------------------------------------
inline std::string const & DataTable::getName() const
{
return m_name;
}
#endif
@@ -0,0 +1,108 @@
// ======================================================================
//
// DataTableCell.cpp
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/DataTableCell.h"
#include "sharedFoundation/Crc.h"
#include "sharedFoundation/CrcString.h"
#include "sharedFoundation/MemoryBlockManager.h"
// ======================================================================
MemoryBlockManager *DataTableCell::ms_memoryBlockManager;
// ----------------------------------------------------------------------
void DataTableCell::install()
{
DEBUG_FATAL(ms_memoryBlockManager, ("DataTableCell is not installed"));
ms_memoryBlockManager = new MemoryBlockManager("DataTableCell::ms_memoryBlockManager", true, sizeof(DataTableCell), 0, 0, 0);
}
// ----------------------------------------------------------------------
void DataTableCell::remove()
{
DEBUG_FATAL(!ms_memoryBlockManager,("DataTableCell is not installed"));
delete ms_memoryBlockManager;
ms_memoryBlockManager = 0;
}
// ----------------------------------------------------------------------
void *DataTableCell::operator new(size_t size)
{
UNREF(size);
DEBUG_FATAL(!ms_memoryBlockManager,("DataTableCell is not installed"));
DEBUG_FATAL(size != sizeof(DataTableCell),("bad size"));
return ms_memoryBlockManager->allocate();
}
// ----------------------------------------------------------------------
void DataTableCell::operator delete(void *pointer)
{
DEBUG_FATAL(!ms_memoryBlockManager,("DataTableCell is not installed"));
ms_memoryBlockManager->free(pointer);
}
// ----------------------------------------------------------------------
DataTableCell::DataTableCell(int value)
: m_type(CT_int)
{
m_value.m_i=value;
}
// ----------------------------------------------------------------------
DataTableCell::DataTableCell(float value)
: m_type(CT_float)
{
m_value.m_f = value;
}
// ----------------------------------------------------------------------
DataTableCell::DataTableCell(const char *value)
: m_type(CT_string)
{
if (!value || !*value)
{
m_value.m_s.m_sz = 0;
m_value.m_s.m_crc = 0;
}
else
{
int len = strlen(value) + 1;
char *s = new char[len];
// normalize copies the output into s, so we can get the crc
CrcString::normalize(s, value);
m_value.m_s.m_crc = Crc::calculate(s);
// copy the correct (unnormalized) string into s (this saves us the allocation of a tmp string)
strcpy(s, value);
m_value.m_s.m_sz = s;
}
}
// ----------------------------------------------------------------------
DataTableCell::~DataTableCell()
{
if (m_type==CT_string && m_value.m_s.m_sz!=0)
{
delete [] const_cast<char *>(m_value.m_s.m_sz);
#ifdef _DEBUG
m_value.m_s.m_sz=0;
#endif
}
}
@@ -0,0 +1,81 @@
// ======================================================================
//
// DataTableCell.h
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_DataTableCell_H
#define INCLUDED_DataTableCell_H
// ======================================================================
class MemoryBlockManager;
// ======================================================================
class DataTableCell
{
public:
static void install();
static void remove();
static void *operator new(size_t size, void *p) { UNREF(size); return p; }
static void *operator new(size_t size);
static void operator delete(void *pointer);
enum CellType {
CT_string
,CT_int
,CT_float
};
explicit DataTableCell(int value);
explicit DataTableCell(float value);
explicit DataTableCell(const char *value);
~DataTableCell();
CellType getType() const { return m_type; }
int getIntValue() const { return m_value.m_i; }
float getFloatValue() const { return m_value.m_f; }
const char *getStringValue() const;
int getStringValueCrc() const { return m_value.m_s.m_crc; }
private:
const CellType m_type;
struct
{
union
{
int m_i;
float m_f;
struct
{
const char *m_sz;
int m_crc;
} m_s;
};
} m_value;
DataTableCell &operator=(const DataTableCell &);
static MemoryBlockManager *ms_memoryBlockManager;
};
inline const char *DataTableCell::getStringValue() const
{
if (m_value.m_s.m_sz)
{
return m_value.m_s.m_sz;
}
else
{
return "";
}
}
// ======================================================================
#endif
@@ -0,0 +1,483 @@
// ======================================================================
//
// DataTableColumnType.cpp
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/DataTableColumnType.h"
#include "UnicodeUtils.h"
#include "sharedFoundation/Crc.h"
#include "sharedUtility/DataTable.h"
#include "sharedUtility/DataTableManager.h"
#include <cstdio>
#include <map>
// ----------------------------------------------------------------------
static std::string chomp(std::string const &str)
{
std::string result = str;
while(!result.empty() && result[0] == ' ')
result.erase(0, 1);
while(!result.empty() && result[result.size() - 1] == ' ')
result.erase(result.size() - 1, 1);
return result;
}
static std::string getDelimStr(std::string const &str, char left, char right)
{
std::string::size_type lPos = str.find(left);
std::string::size_type rPos = str.rfind(right);
if (lPos == std::string::npos || rPos == std::string::npos)
return "";
return str.substr(lPos+1, rPos-lPos-1);
}
// ----------------------------------------------------------------------
bool consumePackedObjVarIntField(char const *&s)
{
while (*s)
{
char const c = *s;
++s;
if (c == '|')
return true;
else if ( c != '-' && !isdigit(c))
break;
}
return false;
}
// ----------------------------------------------------------------------
bool consumePackedObjVarStringField(char const *& s)
{
while (*s)
{
char const c = *s++;
if (c == '|')
return true;
}
return false;
}
// ----------------------------------------------------------------------
DataTableColumnType::~DataTableColumnType ()
{
delete m_enumMap;
m_enumMap = 0;
delete m_defaultCell;
m_defaultCell = 0;
}
// ----------------------------------------------------------------------
DataTableColumnType::DataTableColumnType(std::string const &desc) :
m_typeSpecString(desc),
m_type(DT_Unknown),
m_basicType(DT_Unknown),
m_defaultValue(),
m_enumMap(0),
m_defaultCell(0)
{
// desc may only look like:
// {ifshbep}[def] or e(x=0,y=1,z=2,...)[def]
// first, split into type and default value
int type = tolower(desc[0]);
m_defaultValue = getDelimStr(desc, '[', ']');
if (type == 'i')
{
m_type = m_basicType = DT_Int;
if (m_defaultValue.length() == 0)
m_defaultValue = "0";
}
else if (type == 'f')
{
m_type = m_basicType = DT_Float;
if (m_defaultValue.length() == 0)
m_defaultValue = "0";
}
else if (type == 's')
{
m_type = m_basicType = DT_String;
}
else if (type == 'c')
{
m_type = m_basicType = DT_Comment;
}
else if (type == 'h')
{
m_type = DT_HashString;
m_basicType = DT_Int;
}
else if (type == 'p')
{
m_type = DT_PackedObjVars;
m_basicType = DT_String;
}
else if (type == 'b')
{
m_type = DT_Bool;
m_basicType = DT_Int;
if (m_defaultValue != "1")
m_defaultValue = "0";
}
else if (type == 'e')
{
m_enumMap = new StringIntMap;
m_type = DT_Enum;
m_basicType = DT_Int;
// build the enumeration map
std::string enumList = getDelimStr(desc, '(', ')');
enumList += ",";
// enumList looks like "foo=0,bar=1,life=42,"
std::string::size_type eqPos;
while ((eqPos = enumList.find('=')) != std::string::npos)
{
std::string::size_type endPos = enumList.find(',');
std::string label = enumList.substr(0, eqPos);
std::string val = enumList.substr(eqPos+1, endPos-eqPos-1);
(*m_enumMap)[label] = static_cast<int>(strtol(val.c_str(), NULL, 0));
enumList.erase(0, endPos+1);
}
// assure the default is a member of the enumeration
if (m_enumMap->find(m_defaultValue) == m_enumMap->end())
{
WARNING(true, ("Default value [%s] is not a member of enumeration", m_defaultValue.c_str()));
m_basicType = DT_Unknown;
}
}
else if (type == 'v')
{
m_enumMap = new StringIntMap;
m_type = DT_BitVector;
m_basicType = DT_Int;
// build the enumeration map
std::string enumList = getDelimStr(desc, '(', ')');
enumList += ",";
// enumList looks like "foo=0,bar=1,life=42,"
std::string::size_type eqPos;
while ((eqPos = enumList.find('=')) != std::string::npos)
{
std::string::size_type endPos = enumList.find(',');
std::string label = enumList.substr(0, eqPos);
std::string val = enumList.substr(eqPos+1, endPos-eqPos-1);
int bit = static_cast<int>(strtol(val.c_str(), NULL, 0));
if((bit < 1) || (bit > 32))
{
WARNING(true, ("Flags value [%s] is not a whole number from 1 to 32", label.c_str()));
m_basicType = DT_Unknown;
}
(*m_enumMap)[label] = 1 << (bit - 1);
enumList.erase(0, endPos+1);
}
// assure the default is a member of the enumeration
if(strcmp(m_defaultValue.c_str(), "NONE") != 0)
{
if (m_enumMap->find(m_defaultValue) == m_enumMap->end())
{
WARNING(true, ("Default value [%s] is not a member of enumeration", m_defaultValue.c_str()));
m_basicType = DT_Unknown;
}
}
}
else if (type == 'z')
{
m_enumMap = new StringIntMap;
m_type = DT_Enum;
m_basicType = DT_Int;
// get the filename
std::string fileName = getDelimStr(desc, '(', ')');
DataTable * enumTable = DataTableManager::getTable(fileName, true);
if (!enumTable)
{
m_basicType = DT_Unknown;
return;
}
int enumCount = enumTable->getNumRows();
int x;
std::string firstKey;
for (x=0; x<enumCount; ++x)
{
std::string key = enumTable->getStringValue(0, x);
Unicode::trim(key);
int value = enumTable->getIntValue(1,x);
if (x==0)
firstKey = key;
(*m_enumMap)[key] = value;
}
// assure the default is a member of the enumeration
if (m_enumMap->find(m_defaultValue) == m_enumMap->end())
{
m_defaultValue = firstKey;
}
}
else
m_basicType = DT_Unknown;
createDefaultCell();
}
// ----------------------------------------------------------------------
void DataTableColumnType::createDefaultCell()
{
std::string value;
IS_NULL(m_defaultCell);
// If mangleValue does not update the input value string,
// then the default cell will have a value of 0 for floats and ints
// and a value of empty string for strings.
IGNORE_RETURN(mangleValue(value));
switch(m_basicType)
{
case DT_Int:
m_defaultCell = new DataTableCell(static_cast<int>(strtol(value.c_str(), NULL, 0)));
break;
case DT_Float:
m_defaultCell = new DataTableCell(static_cast<float>(atof(value.c_str())));
break;
case DT_String:
case DT_Comment:
case DT_Unknown:
default:
m_defaultCell = new DataTableCell(value.c_str());
break;
}
}
// ----------------------------------------------------------------------
DataTableColumnType::DataTableColumnType(DataTableColumnType const &rhs) :
m_typeSpecString(rhs.m_typeSpecString),
m_type(rhs.m_type),
m_basicType(rhs.m_basicType),
m_defaultValue(rhs.m_defaultValue),
m_enumMap(rhs.m_enumMap ? new StringIntMap (*rhs.m_enumMap) : 0),
m_defaultCell(0)
{
createDefaultCell();
}
// ----------------------------------------------------------------------
DataTableColumnType& DataTableColumnType::operator=(DataTableColumnType const &rhs)
{
if (&rhs != this)
{
m_typeSpecString = rhs.m_typeSpecString;
m_type = rhs.m_type;
m_basicType = rhs.m_basicType;
m_defaultValue = rhs.m_defaultValue;
if(rhs.m_enumMap)
{
if(!m_enumMap)
m_enumMap = new StringIntMap;
*m_enumMap = *rhs.m_enumMap;
}
else
{
delete m_enumMap;
m_enumMap = 0;
}
delete m_defaultCell;
m_defaultCell = 0;
createDefaultCell();
}
return *this;
}
// ----------------------------------------------------------------------
std::string const &DataTableColumnType::getTypeSpecString() const
{
return m_typeSpecString;
}
// ----------------------------------------------------------------------
DataTableColumnType::DataType DataTableColumnType::getType() const
{
return m_type;
}
// ----------------------------------------------------------------------
DataTableColumnType::DataType DataTableColumnType::getBasicType() const
{
return m_basicType;
}
// ----------------------------------------------------------------------
bool DataTableColumnType::lookupEnum(std::string const &label, int &result) const
{
NOT_NULL(m_enumMap);
std::string localLabel = chomp(label);
const StringIntMap::const_iterator i = m_enumMap->find(localLabel);
if (i != m_enumMap->end())
{
result = (*i).second;
return true;
}
return false;
}
// ----------------------------------------------------------------------
bool DataTableColumnType::lookupBitVector(std::string const &label, int &result) const
{
std::string localLabel = label;
if(strcmp(label.c_str(), "NONE") == 0)
{
result = 0;
return true;
}
bool foundAny = false;
localLabel += ",";
// enumList looks like "foo,bar,life,"
std::string::size_type eqPos;
while ((eqPos = localLabel.find(',')) != std::string::npos)
{
std::string::size_type endPos = localLabel.find(',');
std::string subLabel = chomp(localLabel.substr(0, eqPos));
int subResult;
if(lookupEnum(subLabel, subResult))
{
foundAny = true;
result |= subResult;
}
else
{
DEBUG_WARNING(true, ("DataTableColumnType::lookupEnumExtended found invalid enum value '%s'", subLabel.c_str()));
}
localLabel.erase(0, endPos+1);
}
return foundAny;
}
// ----------------------------------------------------------------------
bool DataTableColumnType::mangleValue(std::string &value) const
{
// if the value passed in is empty, we mangle to the default value
if (value.length() == 0)
{
if (m_defaultValue == "required" || m_defaultValue == "unique")
return false;
else
value = m_defaultValue;
}
// special validation code for packed objvars
if (m_type == DT_PackedObjVars)
{
// packed objvars are of the form:
// nameString|typeInt|valueString|nameString|typeInt|valueString|$|
// where || may be used in the string fields to represent a |
char const *s = value.c_str();
while (*s)
{
// name
if (s[0] == '$' && s[1] == '|' && s[2] == '\0')
break;
if (!consumePackedObjVarStringField(s))
return false;
// type
if (!consumePackedObjVarIntField(s))
return false;
// value
if (!consumePackedObjVarStringField(s))
return false;
}
}
// only basic type DT_Int are complex types that use value mangling other
// than default values
if (m_basicType != DT_Int || m_type == DT_Int)
return true;
// complex type which needs mangling
switch (m_type)
{
case DT_Bool:
{
if (value == "0" || value == "1")
return true;
}
break;
case DT_HashString:
{
// conversion to integer crc
int val;
if (value.length())
val = Crc::normalizeAndCalculate(value.c_str());
else
val = Crc::crcNull;
char buf[16];
sprintf(buf, "%d", val);
value = buf;
return true;
}
break;
case DT_Enum:
{
// enumeration lookup
int val = 0;
if (lookupEnum(value, val))
{
char buf[16];
sprintf(buf, "%d", val);
value = buf;
return true;
}
}
break;
case DT_BitVector:
{
// enumeration lookup
int val = 0;
if (lookupBitVector(value, val))
{
char buf[16];
sprintf(buf, "%d", val);
value = buf;
return true;
}
}
break;
default:
break;
}
return false;
}
// ----------------------------------------------------------------------
bool DataTableColumnType::areUniqueCellsRequired() const
{
return m_defaultValue == "unique";
}
// ======================================================================
@@ -0,0 +1,70 @@
// ======================================================================
//
// DataTableColumnType.h
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_DataTableColumnType_H
#define INCLUDED_DataTableColumnType_H
#include <string>
class DataTableCell;
class DataTableColumnType
{
public:
explicit DataTableColumnType(std::string const &desc);
~DataTableColumnType ();
DataTableColumnType(DataTableColumnType const &rhs);
DataTableColumnType &operator=(DataTableColumnType const &rhs);
enum DataType
{
DT_Int,
DT_Float,
DT_String,
DT_Unknown,
DT_Comment,
// specializations of DT_Int basic type
DT_HashString,
DT_Enum,
DT_Bool,
// specializations of DT_String basic type
DT_PackedObjVars,
DT_BitVector,
};
DataType getType() const;
DataType getBasicType() const;
std::string const &getTypeSpecString() const;
bool mangleValue(std::string &value) const;
DataTableCell const *getDefaultCell() const;
bool areUniqueCellsRequired() const;
private:
bool lookupEnum(std::string const &label, int &result) const;
bool lookupBitVector(std::string const &label, int &result) const;
private:
DataTableColumnType();
void createDefaultCell();
std::string m_typeSpecString;
DataType m_type;
DataType m_basicType;
std::string m_defaultValue;
typedef stdmap<std::string, int>::fwd StringIntMap;
StringIntMap * m_enumMap;
DataTableCell * m_defaultCell;
};
inline const DataTableCell * DataTableColumnType::getDefaultCell() const
{
return m_defaultCell;
}
#endif // INCLUDED_DataTableColumnType_H
@@ -0,0 +1,197 @@
// ======================================================================
//
// DataTableManager.cpp
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/DataTableManager.h"
#include "sharedFile/Iff.h"
#include "sharedFile/TreeFile.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedUtility/DataTable.h"
#include "sharedUtility/DataTableCell.h"
#include <map>
// ----------------------------------------------------------------------
DataTable * DataTableManager::m_cachedTable = 0;
std::string DataTableManager::m_cachedTableName = "";
bool DataTableManager::m_errorChecking = false;
std::map<std::string, DataTable *> DataTableManager::m_tables;
bool DataTableManager::m_installed = false;
std::multimap<std::string, DataTableReloadCallback> DataTableManager::m_reloadCallbacks;
// ----------------------------------------------------------------------
void DataTableManager::install(bool verboseErrorChecking)
{
FATAL(m_installed, ("DataTableManager::install: already installed."));
m_errorChecking = verboseErrorChecking;
ExitChain::add(DataTableManager::remove, "DataTableManager::remove");
DataTableCell::install();
m_installed = true;
}
// ----------------------------------------------------------------------
void DataTableManager::remove()
{
FATAL(!m_installed, ("DataTableManager::remove: not installed."));
m_cachedTable = 0;
m_cachedTableName = "";
std::map<std::string, DataTable *>::iterator i;
for (i=m_tables.begin(); i != m_tables.end(); ++i)
{
DataTable * toDelete = i->second;
delete toDelete;
}
m_tables.clear();
m_reloadCallbacks.clear();
DataTableCell::remove();
m_installed = false;
}
// ----------------------------------------------------------------------
DataTable* DataTableManager::open(const std::string& table)
{
FATAL(!m_installed, ("DataTableManager::open: not installed."));
DataTable *retVal = getTable(table, false);
if (retVal)
return retVal;
if (!TreeFile::exists(table.c_str()))
{
DEBUG_WARNING(true, ("Could not find treefile table for open [%s]", table.c_str()));
return 0;
}
Iff iff(table.c_str(), false);
retVal = new DataTable;
retVal->load(iff);
m_cachedTable = retVal;
m_cachedTableName = table;
m_tables[table] = retVal;
return retVal;
}
// ----------------------------------------------------------------------
void DataTableManager::close(const std::string& table)
{
// FATAL(!m_installed, ("DataTableManager::close: not installed."));
std::map<std::string, DataTable *>::iterator i = m_tables.find(table);
if (i == m_tables.end())
{
DEBUG_WARNING(true, ("Could not find loaded table for close [%s]", table.c_str()));
return;
}
if (m_cachedTable == i->second)
{
DEBUG_WARNING(m_cachedTableName != table, ("Cached name got out of sync"));
m_cachedTableName = "";
m_cachedTable = 0;
}
DataTable * dt = i->second;
m_tables.erase(i);
delete dt;
}
// ----------------------------------------------------------------------
DataTable * DataTableManager::getTable(const std::string& table, bool openIfNotFound)
{
// FATAL(!m_installed, ("DataTableManager::getTable: not installed."));
if (m_cachedTableName == table)
return m_cachedTable;
std::map<std::string, DataTable *>::iterator i = m_tables.find(table);
if (i == m_tables.end())
{
if (openIfNotFound)
{
DataTable * dt = open(table);
if (!dt)
{
DEBUG_WARNING(true, ("Could not find table [%s]", table.c_str()));
return NULL;
}
else
{
m_cachedTableName = table;
m_cachedTable = dt;
return dt;
}
}
else
{
return NULL;
}
}
m_cachedTableName = table;
m_cachedTable = i->second;
return i->second;
}
// ----------------------------------------------------------------------
DataTable* DataTableManager::reload(const std::string & table)
{
// FATAL(!m_installed, ("DataTableManager::reload: not installed."));
close(table);
DataTable * const dataTable = open(table);
if (dataTable != NULL)
{
std::multimap<std::string, DataTableReloadCallback>::const_iterator i = m_reloadCallbacks.lower_bound(table);
for (; i != m_reloadCallbacks.end() && (*i).first == table; ++i)
(*((*i).second))(*dataTable);
}
return dataTable;
}
// ----------------------------------------------------------------------
DataTable* DataTableManager::reloadIfOpen(const std::string & table)
{
if(isOpen(table))
return reload(table);
else
return NULL;
}
// ----------------------------------------------------------------------
void DataTableManager::addReloadCallback(const std::string& table, DataTableReloadCallback callbackFunction)
{
IGNORE_RETURN(m_reloadCallbacks.insert(std::make_pair(table, callbackFunction)));
}
// ----------------------------------------------------------------------
bool DataTableManager::isOpen(const std::string& table)
{
std::map<std::string, DataTable *>::const_iterator const i = m_tables.find(table);
return i != m_tables.end();
}
// ======================================================================
@@ -0,0 +1,50 @@
// ======================================================================
//
// DataTableManager.h
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_DataTableManager_H
#define INCLUDED_DataTableManager_H
// ======================================================================
class DataTable;
// ======================================================================
typedef void (*DataTableReloadCallback)(DataTable const &);
class DataTableManager
{
public:
static void install(bool verboseErrorChecking = true);
static void close(const std::string& table);
static DataTable * getTable(const std::string& table, bool openIfNotFound = false);
static DataTable * reload(const std::string& table);
static DataTable * reloadIfOpen(const std::string& table);
static void addReloadCallback(const std::string& table, DataTableReloadCallback callbackFunction);
static bool isOpen(const std::string& table);
private:
static void remove();
static DataTable * open(const std::string& table);
DataTableManager();
~DataTableManager();
static DataTable* m_cachedTable;
static std::string m_cachedTableName;
static bool m_errorChecking;
static stdmap<std::string, DataTable *>::fwd m_tables;
static bool m_installed;
static stdmultimap<std::string, DataTableReloadCallback>::fwd m_reloadCallbacks;
};
// ======================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
// ======================================================================
//
// DataTableWriter.h
//
// copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_DataTableWriter_H
#define INCLUDED_DataTableWriter_H
#include "DataTableColumnType.h"
#include <list>
#include <string>
#include <vector>
class Iff;
class XmlTreeNode;
//----------------------------------------------------------------------
class DataTableWriter
{
public:
DataTableWriter();
~DataTableWriter();
void setOutputPath (const char * path);
void loadFromSpreadsheet (const char * filename);
bool save (const char * outputFileName, bool optional = false) const;
bool save (bool optional = false) const;
void save (Iff & iff) const;
bool saveTable( const char* tableName, const char* fileName = 0, bool optional = false ) const;
void getTableNames(std::vector<std::string> & v) const;
void getTableOutputFileName( const char* tableName, std::string& fileName ) const;
static bool isXmlFile(const char * filename);
private:
class NamedDataTable;
typedef std::list<NamedDataTable *> NamedDataTableList;
bool _checkIntegrity(const NamedDataTable * ndt) const;
void _loadFromSpreadsheetTab (const char * filename);
void _loadFromSpreadsheetXml (const char * filename);
void _loadWorksheet (NamedDataTable * ndt, XmlTreeNode nodeWorksheet);
void _loadDataTableSchema(NamedDataTable * ndt, XmlTreeNode parentNode);
void _loadDataTableRow(NamedDataTable * ndt, XmlTreeNode rowNode);
void _loadColumnNames(NamedDataTable * ndt, const char* row);
void _loadTypes(NamedDataTable * ndt, const char* row);
void _loadRow(NamedDataTable * ndt, const char* row, int index);
void _saveColumns(NamedDataTable * ndt, Iff& iff) const;
void _saveTypes(NamedDataTable * ndt, Iff& iff) const;
void _saveRows(NamedDataTable * ndt, Iff& iff) const;
bool _writeTable(NamedDataTable * ndt, const char * outputFile, bool optional) const;
void _saveTableToIff(Iff & iff, NamedDataTable * ndt) const;
static DataTableCell *_getNewCell(DataTableColumnType const &columnType, char const *contents);
NamedDataTableList m_tables;
std::string m_path;
};
//----------------------------------------------------------------------
#endif
@@ -0,0 +1,289 @@
//
// FileName.h
// asommers 5-26-99
//
// copyright 1999, bootprint entertainment
//
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/FileName.h"
#include <cstdio>
//-------------------------------------------------------------------
FileName::Table FileName::pathTable [P_COUNT] =
{
{"", "" }, // P_none
{"animationmap/", "map"}, // P_animationMap
{"camera/", "iff"}, // P_camera
{"inputmap/", "iff"}, // P_inputmap
{"appearance/", "" }, // P_appearance
{"animation", "" }, // P_animation
{"music/", "mus"}, // P_music
{"object/", "iff"}, // P_object
{"sample/", "sam"}, // P_sound
{"scene/", "scn"}, // P_scene
{"script/", "iff"}, // P_script
{"shader/", "sht"}, // P_shader
{"effect/", "eft"}, // P_effect
{"terrain/", "" }, // P_terrain
{"texture/", "dds"} // P_texture
};
//-------------------------------------------------------------------
FileName::FileName (const char* const newName) :
fullName (0)
{
set (newName);
}
FileName::FileName (FileName::Path path, const char* filename, const char* ext)
: fullName (0)
{
//-- verify args
DEBUG_FATAL (path < P_none || path >= P_COUNT, ("FileName::FileName - bad path!"));
DEBUG_FATAL (!filename, ("FileName::FileName - filename is 0"));
//-- make sure we have an extention
if (!ext)
ext = pathTable [path].ext;
// see if the filename already begins with the path
const char *prePath = pathTable [path].path;
if (prePath != NULL && *prePath != '\0')
{
if (strncmp(filename, prePath, strlen(prePath)) == 0)
prePath = "";
}
// see if the filename already ends in the extension
if (ext != NULL && *ext != '\0')
{
int extLen = strlen(ext);
int filenameLen = strlen(filename);
if (filenameLen > extLen + 1)
{
for (--extLen, --filenameLen; extLen >= 0; --extLen, --filenameLen)
{
if (ext[extLen] != filename[filenameLen])
break;
}
if (extLen == -1 && filename[filenameLen] == '.')
ext = "";
}
}
fullName = new char [strlen(prePath) + strlen(filename) + 1 + strlen(ext) + 1];
sprintf(fullName, "%s%s%s%s", prePath, filename, strlen(ext) ? "." : "", ext);
}
//-------------------------------------------------------------------
FileName::FileName (const char* path, const char* filename, const char* ext) :
fullName (0)
{
NOT_NULL (path);
NOT_NULL (filename);
fullName = new char [strlen(path) + 1 + strlen(filename) + 1 + (ext ? strlen(ext) : 0) + 1];
sprintf(fullName, "%s%s%s%s%s", path, strlen (path) ? "/" : "", filename, (ext && strlen (ext)) ? "." : "", ext ? ext : "");
}
//-------------------------------------------------------------------
FileName::~FileName (void)
{
delete [] fullName;
fullName = 0;
}
//-------------------------------------------------------------------
void FileName::set (const char* const newName)
{
DEBUG_FATAL (!newName, ("FileName::set - newName is 0"));
if (fullName)
{
delete [] fullName;
fullName = 0;
}
if (newName)
fullName = DuplicateString (newName);
}
//-------------------------------------------------------------------
void FileName::stripPathAndExt (void)
{
stripPathAndExt (fullName, istrlen (fullName));
}
//-------------------------------------------------------------------
void FileName::stripPath (void)
{
stripPath (fullName, istrlen (fullName));
}
//-------------------------------------------------------------------
void FileName::stripSpecificPathAndExt (Path path)
{
stripSpecificPathAndExt (path, fullName, istrlen (fullName));
}
//-------------------------------------------------------------------
void FileName::stripPathAndExt (char* nameBuffer, int nameBufferLength)
{
NOT_NULL (nameBuffer);
//-- warning: this function modifies the buffer of the argument
char buffer [1000];
int len = istrlen (nameBuffer);
char* start = nameBuffer;
char* end = nameBuffer + len;
char* curr = end;
//-- start from end of string and search backward for '\' or '/'
while (curr != start && !(*curr == '\\' || *curr == '/'))
curr--;
//-- start from curr and search to the end for '.'
if (*curr == '\\' || *curr == '/')
curr++;
start = curr;
while (curr < end && *curr != '.')
curr++;
//-- copy string
end = curr;
curr = start;
len = end - start;
int i;
for (i = 0; i < len && i < nameBufferLength; i++)
buffer [i] = *curr++;
buffer [i] = 0;
strncpy (nameBuffer, buffer, nameBufferLength);
}
//-------------------------------------------------------------------
void FileName::stripPath (char* nameBuffer, int nameBufferLength)
{
NOT_NULL (nameBuffer);
//-- warning: this function modifies the buffer of the argument
char buffer [1000];
int len = istrlen (nameBuffer);
char* start = nameBuffer;
char* end = nameBuffer + len;
char* curr = end;
//-- start from end of string and search backward for '\' or '/'
while (curr != start && !(*curr == '\\' || *curr == '/'))
curr--;
if (curr != start && (*curr == '\\' || *curr == '/'))
curr++;
//-- copy string
start = curr;
len = end - start;
int i;
for (i = 0; i < len && i < nameBufferLength; i++)
buffer [i] = *curr++;
if (i >= nameBufferLength)
i--;
DEBUG_FATAL (i < 0, ("i < 0"));
buffer [i] = 0;
strncpy (nameBuffer, buffer, nameBufferLength);
nameBuffer [nameBufferLength - 1] = 0;
}
//-------------------------------------------------------------------
/* This function strips the path and ext from the nameBuffer that correspond to the given path.
* It will do nothing if the path and ext do not match the one given to it in the path parameter.
*/
void FileName::stripSpecificPathAndExt (Path path, char* nameBuffer, int nameBufferLength)
{
//-- warning: this function modifies the buffer of the argument
NOT_NULL(nameBuffer);
int len = istrlen(nameBuffer);
char* start = nameBuffer;
char* end = nameBuffer + len;
char buffer[1000];
//string compare nameBuffer to path.path for strlen(path.path)-1 to make sure it is correct.
//-1 because we don't care about the slash (could be back or forward)
//@todo these compares could be debug only.
if (strncmp(nameBuffer, pathTable[path].path, strlen(pathTable[path].path) - 1) != 0)
{
DEBUG_REPORT_LOG(true, ("Error in stripSpecificPathAndExt...nameBuffer does not match path\n"));
return;
}
//correct path, now check extension.
//first make sure this path has an extension
if (strlen(pathTable[path].ext) > 0)
{
end = strrchr(nameBuffer, '.');
//make sure to compare strings starting just after the dot
if (!end || strncmp(end + 1, pathTable[path].ext, strlen(pathTable[path].ext)) != 0)
{
DEBUG_REPORT_LOG(true, ("Error in stripSpecificPathAndExt...nameBuffer does not match path\n"));
return;
}
*end = '\0'; //End points to '.' Strip the extension
}
else //We aren't supposed to have an ext. Make sure we don't
{
char* tmp = strrchr(nameBuffer, '.');
if (tmp)
{
DEBUG_REPORT_LOG(true, ("Error in stripSpecificPathAndExt...nameBuffer does not match path\n"));
return;
}
}
//correct extension. End is set to the correct place...just before the dot.
//or in the case of no extension, the last character in the string.
//advance start to after path. Make sure to skip slashes.
start += strlen(pathTable[path].path);
while (*start == '\\' || *start == '/')
start++;
//copy from start to end (which is \0) into tmp buffer
strncpy (buffer, start, 1000);
//move temp buffer into return.
strncpy (nameBuffer, buffer, nameBufferLength);
}
//-------------------------------------------------------------------
#if 0
DEBUG_REPORT_LOG_PRINT (true, ("%s\n", FileName (FileName::P_none, "test")));
DEBUG_REPORT_LOG_PRINT (true, ("%s\n", FileName (FileName::P_none, "test", "iff")));
DEBUG_REPORT_LOG_PRINT (true, ("%s\n", FileName (FileName::P_sound, "test")));
DEBUG_REPORT_LOG_PRINT (true, ("%s\n", FileName (FileName::P_sound, "test", "iff")));
#endif
@@ -0,0 +1,99 @@
// ======================================================================
//
// FileName.h
// asommers 5-26-99
//
// copyright 1999, bootprint entertainment
//
// ======================================================================
#ifndef INCLUDED_FileName_H
#define INCLUDED_FileName_H
// ======================================================================
class FileName
{
public:
enum Path
{
P_none,
P_animationMap,
P_camera,
P_inputmap,
P_appearance,
P_animation,
P_music,
P_object,
P_sample,
P_scene,
P_script,
P_shader,
P_shaderEffect,
P_terrain,
P_texture,
P_COUNT
};
private:
struct Table
{
const char* path;
const char* ext;
};
private:
static Table pathTable [P_COUNT];
private:
char* fullName;
private:
FileName ();
FileName (const FileName&);
FileName& operator= (const FileName&);
public:
explicit FileName (const char* const newName);
FileName (const char* path, const char* filename, const char* ext=0);
FileName (Path path, const char* filename, const char* ext=0);
~FileName ();
operator const char* () const; //lint !e1930 //-- conversion operator found
const char* getString () const;
void set (const char* const newName);
void stripPathAndExt ();
void stripPath ();
void stripSpecificPathAndExt (Path path);
static void stripPathAndExt (char* nameBuffer, int nameBufferLength);
static void stripPath (char* nameBuffer, int nameBufferLength);
static void stripSpecificPathAndExt (Path path, char* nameBuffer, int nameBufferLength);
};
//-------------------------------------------------------------------
inline FileName::operator const char* () const
{
return fullName;
}
//-------------------------------------------------------------------
inline const char* FileName::getString () const
{
return fullName;
}
// ======================================================================
#endif
@@ -0,0 +1,19 @@
// ======================================================================
//
// FirstUtility.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_FirstUtility_H
#define INCLUDED_FirstUtility_H
// ======================================================================
#include "sharedDebug/FirstSharedDebug.h"
#include "sharedFoundation/FirstSharedFoundation.h"
// ======================================================================
#endif
@@ -0,0 +1,71 @@
//======================================================================
//
// HttpGetEncoder.cpp
// copyright (c) 2006 Sony Online Entertainment
//
//======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "HttpGetEncoder.h"
//======================================================================
namespace HttpGetEncoderNamespace
{
// note: This is a pretty aggressive encoder. A few more characters
// (such as parens) could be added, however extra encoding is always legal.
std::string encodeString(const std::string & toEncode)
{
char buf[3];
std::string output;
for(unsigned int i = 0; i < toEncode.length(); ++i)
{
// check to see if the char is valid.
char current = toEncode[i];
// if it is, append it.
if((current >= 'a' && current <= 'z') ||
(current >='A' && current <= 'Z') ||
(current >='0' && current <= '9') ||
(current == '-'))
{
output = output + current;
}
// if it is a space, add a + sign.
else if(current == ' ')
{
output = output + "+";
}
// if not, append the ascii code.
else
{
output = output + "%";
snprintf(buf, 3, "%02x", current);
output = output + buf;
}
}
return output;
}
}
std::string HttpGetEncoder::getUrl(const std::string & urlBase, const GetParams & params)
{
std::string outUrl = urlBase;
std::string paramList;
for(GetParams::const_iterator it = params.begin(); it != params.end(); ++it)
{
if(it->first != "" && it->second != "")
paramList = paramList + HttpGetEncoderNamespace::encodeString(it->first) + "="
+ HttpGetEncoderNamespace::encodeString(it->second) + "&";
}
// trim the trailing &
if(paramList.length() > 0)
{
paramList = paramList.substr(0, paramList.length() - 1);
// if we still have data, append it.
if( paramList.length() > 0)
outUrl = outUrl + "?" + paramList;
}
return outUrl;
}
@@ -0,0 +1,25 @@
//===================================================================
//
// HttpGetEncoder.h
//
// copyright 2006, Sony Online Entertainment
//
//===================================================================
#ifndef INCLUDED_HttpGetEncoder_H
#define INCLUDED_HttpGetEncoder_H
#include <string>
#include <map>
class HttpGetEncoder
{
public:
typedef std::map<std::string, std::string> GetParams;
static std::string getUrl( const std::string & UrlBase, const GetParams & params);
private:
HttpGetEncoder();
};
#endif // INCLUDED_HttpGetEncoder_H
@@ -0,0 +1,265 @@
// ======================================================================
//
// IndexedCache.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/IndexedCache.h"
#include "Archive/Archive.h"
#include "Archive/ByteStream.h"
#include "fileInterface/StdioFile.h"
IndexedCache::IndexedCache(const std::string &i_filename, int i_length, int i_version)
: filename(i_filename), length(i_length), version(i_version)
{
lockExclusive(filename);
file = new StdioFile(filename.c_str(), "r+b");
if (!file->isOpen())
{
delete file;
file = new StdioFile(filename.c_str(), "w+b");
if (!file->isOpen())
{
delete file;
file = 0;
}
}
if (file)
{
if (file->length() == 0)
{
// Write the header out
initializeFile(i_version);
}
else
{
file->seek(AbstractFile::SeekBegin, 0);
Header header;
file->read(&header, sizeof(header));
if (header.elements != i_length || header.version != i_version)
{
initializeFile(i_version);
}
}
}
else
{
length = 0;
}
unlockExclusive(filename);
}
IndexedCache::IndexedCache(const std::string &i_filename)
: filename(i_filename), length(0), version(0)
{
file = new StdioFile(filename.c_str(), "r+b");
if (file->length() > 0)
{
file->seek(AbstractFile::SeekBegin, 0);
Header header;
file->read(&header, sizeof(header));
length = header.elements;
version = header.version;
}
}
IndexedCache::~IndexedCache()
{
delete file;
file = 0;
}
void IndexedCache::initializeFile(int i_version)
{
file->seek(AbstractFile::SeekBegin, 0);
Header header;
header.elements = length;
header.formatVersion = 1;
header.version = i_version;
file->write(sizeof(header), &header);
// Write out a bunch of zero entries
int toWrite = length;
const int COUNT = 8192;
Entry * entries = new Entry[COUNT];
int x;
for (x=0; x<COUNT; ++x)
{
entries[x].offset = 0;
}
while (toWrite > 0)
{
file->write(std::min(toWrite, COUNT) * sizeof(Entry), entries);
toWrite -= COUNT;
}
delete [] entries;
file->flush();
}
/* attempt to get data into the cache.
If there is no data in the cache, returns 0.
If the index is out of range, returns 0 and no error.
*/
Archive::ByteStream * IndexedCache::getData(int index) const
{
if (index < 0 || index >= length)
return 0;
lockForRead();
Entry entry;
readEntry(index, entry);
if (entry.offset == 0)
{
unlock();
return 0;
}
file->seek(AbstractFile::SeekBegin, entry.offset);
Datum datum;
file->read(&datum, sizeof(datum));
unsigned char * data = new unsigned char[datum.length];
file->read(data, datum.length);
Archive::ByteStream * result = new Archive::ByteStream(data, datum.length);
delete [] data;
unlock();
return result;
}
/* Test to see if the data is already in the cache
If there is no data in the cache, returns false.
If the index is out of range, returns true. (The typical
use is to check contains() before creating the bytestream
to write data. This prevents an out-of-range index from
having to generate data)
*/
bool IndexedCache::contains(int index) const
{
if (index < 0 || index >= length)
return true;
lockForRead();
Entry entry;
readEntry(index, entry);
unlock();
return entry.offset != 0;
}
/* Set data into the cache.
The new data is appended and the index is updated, even if the data is already in the cache.
Use contains() to test if needed. This can potentially cause duplicate data to
be entered into the cache twice, but this will typicallly not be a problem.
This is also useful to allow partial caching, updating the cached data as more
information becomes available.
*/
void IndexedCache::setData(int index, Archive::ByteStream const * data)
{
if (index < 0 || index >= length)
return;
lockForWrite();
Entry entry;
file->seek(AbstractFile::SeekEnd, 0);
entry.offset = file->tell();
Datum datum;
datum.index = index;
datum.length = data->getSize();
file->write(sizeof(datum), &datum);
file->write(data->getSize(), data->getBuffer());
writeEntry(index, entry);
file->flush();
unlock();
}
void IndexedCache::readEntry(int index, Entry &o_entry) const
{
file->seek(AbstractFile::SeekBegin, sizeof(Header) + index * sizeof(Entry));
file->read(&o_entry, sizeof(o_entry));
}
void IndexedCache::writeEntry(int index, Entry const &i_entry)
{
file->seek(AbstractFile::SeekBegin, sizeof(Header) + index * sizeof(Entry));
file->write(sizeof(i_entry), &i_entry);
}
void IndexedCache::lockExclusive(const std::string &filename)
{
UNREF(filename);
}
void IndexedCache::unlockExclusive(const std::string &filename)
{
UNREF(filename);
}
void IndexedCache::lockForRead() const
{
}
void IndexedCache::lockForWrite()
{
}
void IndexedCache::unlock() const
{
}
/* Repacks and sorts the file by index order.
Returns false if the repack fails for any reason.
Any attempts to access the file during repacking will fail.
Repacking will fail if the file is already opened for use.
*/
bool IndexedCache::repack(const std::string &filename)
{
lockExclusive(filename);
std::string outputFilename(filename + ".repack");
{
IndexedCache input(filename);
int size = input.getSize();
if (size == 0)
{
unlockExclusive(filename);
return false;
}
IndexedCache output(filename, size, input.getVersion());
int x;
for (x=0; x<size; ++x)
{
Archive::ByteStream * data = input.getData(x);
if (data)
{
output.setData(x, data);
delete data;
}
}
}
_unlink(filename.c_str());
rename(outputFilename.c_str(), filename.c_str());
unlockExclusive(filename);
return true;
}
@@ -0,0 +1,122 @@
// ======================================================================
//
// Callback.h
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_IndexedCache_H
#define INCLUDED_IndexedCache_H
#include <string>
class AbstractFile;
namespace Archive
{
class ByteStream;
};
/*
IndexedCache provides a cache of variable-sized data indexed by an integer.
It is intended to provide a means of storing data which requires a significant amount
of time to produce (on the order of hundreds of milliseconds). Each read requires
at most two seeks; but the index will probably be cached in RAM, and in many cases
the data will as well, especially if the file has been packed.
It is essentially a very simple append-only filesystem.
The structure of the file is as follows:
1. A simple header
2. An array of offsets (from the start of file)
3. A sequence of index/length/arbitrary data
Updates are made by writing the data (never overwriting existing data) and then writing
the index part of the table. Assuming writes commit in order, no incorrect data can
be stored.
File corruption can still occur, however it does not damage data integrity. Appending
data and then crashing before the index can be updated will leave extra data at the end
of the file. Simply iterating through the data allows us to rebuild the most recent index.
*/
class IndexedCache
{
public:
// Open the spatial cache. If it is not present or the stored width, height, and version are different, recreate it.
IndexedCache(const std::string &filename, int length, int version);
virtual ~IndexedCache();
/* attempt to get data into the cache.
If there is no data in the cache, returns 0.
If the index is out of range, returns 0 and no error.
*/
Archive::ByteStream * getData(int index) const;
/* Test to see if the data is already in the cache
If there is no data in the cache, returns false.
If the index is out of range, returns true. (The typical
use is to check contains() before creating the bytestream
to write data. This prevents an out-of-range index from
having to generate data)
*/
bool contains(int index) const;
/* Set data into the cache.
The new data is appended and the index is updated, even if the data is already in the cache.
Use contains() to test if needed. This can potentially cause duplicate data to
be entered into the cache twice, but this will typicallly not be a problem.
This is also useful to allow partial caching, updating the cached data as more
information becomes available.
*/
void setData(int index, Archive::ByteStream const * data);
/* Repacks and sorts the file by index order.
Returns false if the repack fails for any reason.
Any attempts to access the file during repacking will fail.
Repacking will fail if the file is already opened for use.
*/
static bool repack(const std::string &filename);
int getSize() { return length; }
int getVersion() { return version; }
private:
IndexedCache(const std::string &filename);
struct Header
{
int elements;
int formatVersion;
int version;
};
struct Entry
{
int offset;
};
struct Datum
{
int index;
int length;
// char data[length];
};
private:
std::string filename;
int length;
int version;
mutable AbstractFile * file;
void initializeFile(int version);
static void lockExclusive(const std::string &filename); // used to open the file for repacking.
static void unlockExclusive(const std::string &filename);
void lockForRead() const;
void lockForWrite();
void unlock() const;
void readEntry(int index, Entry &o_entry) const;
void writeEntry(int index, Entry const &i_entry);
};
#endif
@@ -0,0 +1,73 @@
//======================================================================
//
// InstallationResourceData.h
// copyright (c) 2001 Sony Online Entertainment
//
//======================================================================
#ifndef INCLUDED_InstallationResourceData_H
#define INCLUDED_InstallationResourceData_H
//======================================================================
#include "Unicode.h"
#include "sharedFoundation/NetworkId.h"
//----------------------------------------------------------------------
/**
* InstallationResource contains information of interest to the client, concerning
* a single resource pool
*/
struct InstallationResourceData
{
std::string m_name;
NetworkId m_id;
std::string m_parentName;
uint8 m_efficiency;
InstallationResourceData (const std::string & name, const NetworkId & id, const std::string& parentName, uint8 efficiency);
InstallationResourceData ();
bool operator== (const InstallationResourceData & rhs) const;
bool operator!= (const InstallationResourceData & rhs) const;
};
//----------------------------------------------------------------------
inline InstallationResourceData::InstallationResourceData (const std::string & name, const NetworkId & id, const std::string& parentName, uint8 efficiency) :
m_name (name),
m_id (id),
m_parentName(parentName),
m_efficiency (efficiency)
{
}
//----------------------------------------------------------------------
inline InstallationResourceData::InstallationResourceData () :
m_name (),
m_id (),
m_parentName(),
m_efficiency (0)
{
}
//----------------------------------------------------------------------
inline bool InstallationResourceData::operator== (const InstallationResourceData & rhs) const
{
return m_id == rhs.m_id && m_name == rhs.m_name && m_efficiency == rhs.m_efficiency && m_parentName == rhs.m_parentName;
}
//----------------------------------------------------------------------
inline bool InstallationResourceData::operator!= (const InstallationResourceData & rhs) const
{
return !(*this == rhs);
}
//======================================================================
#endif
@@ -0,0 +1,44 @@
//======================================================================
//
// InstallationResourceDataArchive.h
// copyright (c) 2001 Sony Online Entertainment
//
//======================================================================
#ifndef INCLUDED_InstallationResourceDataArchive_H
#define INCLUDED_InstallationResourceDataArchive_H
//======================================================================
#include "sharedFoundation/NetworkIdArchive.h"
#include "sharedUtility/InstallationResourceData.h"
#include "unicodeArchive/UnicodeArchive.h"
//-----------------------------------------------------------------------
namespace Archive
{
//-----------------------------------------------------------------------
inline void get(ReadIterator & source, InstallationResourceData & target)
{
get(source, target.m_id);
get(source, target.m_name);
get(source, target.m_parentName);
get(source, target.m_efficiency);
}
//-----------------------------------------------------------------------
inline void put(ByteStream & target, const InstallationResourceData & source)
{
put(target, source.m_id);
put(target, source.m_name);
put(target, source.m_parentName);
put(target, source.m_efficiency);
}
}
//======================================================================
#endif
@@ -0,0 +1,381 @@
// ======================================================================
//
// InteriorLayoutReaderWriter.cpp
// asommers
//
// copyright 2002, sony online entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/InteriorLayoutReaderWriter.h"
#include "sharedFile/Iff.h"
#include "sharedFoundation/LessPointerComparator.h"
#include "sharedFoundation/PersistentCrcString.h"
#include "sharedFoundation/TemporaryCrcString.h"
#include "sharedFoundation/PointerDeleter.h"
#include "sharedMath/Transform.h"
#include <algorithm>
#include <map>
#include <vector>
// ======================================================================
namespace InteriorLayoutReaderWriterNamespace
{
const Tag TAG_INLY = TAG(I,N,L,Y);
const Tag TAG_NODE = TAG(N,O,D,E);
};
using namespace InteriorLayoutReaderWriterNamespace;
// ======================================================================
// InteriorLayoutReaderWriter::Node
// ======================================================================
class InteriorLayoutReaderWriter::Node
{
public:
explicit Node(char const * cellName);
~Node();
CrcString const & getCellName() const;
int getNumberOfObjects() const;
CrcString const & getObjectTemplateName(int index) const;
Transform const & getTransform_o2p(int index) const;
void addObject(char const * objectTemplateName, Transform const & transform_o2p);
private:
Node();
Node(const Node&);
Node & operator=(const Node&);
private:
PersistentCrcString const m_cellName;
typedef std::vector<std::pair<PersistentCrcString, Transform> > ObjectVector;
ObjectVector m_objectVector;
};
// ======================================================================
// PUBLIC InteriorLayoutReaderWriter::Node
// ======================================================================
InteriorLayoutReaderWriter::Node::Node(char const * const cellName) :
m_cellName(cellName, true),
m_objectVector()
{
}
// ----------------------------------------------------------------------
InteriorLayoutReaderWriter::Node::~Node()
{
}
// ----------------------------------------------------------------------
CrcString const & InteriorLayoutReaderWriter::Node::getCellName() const
{
return m_cellName;
}
// ----------------------------------------------------------------------
int InteriorLayoutReaderWriter::Node::getNumberOfObjects() const
{
return static_cast<int>(m_objectVector.size());
}
// ----------------------------------------------------------------------
CrcString const & InteriorLayoutReaderWriter::Node::getObjectTemplateName(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfObjects());
return m_objectVector[static_cast<size_t>(index)].first;
}
// ----------------------------------------------------------------------
Transform const & InteriorLayoutReaderWriter::Node::getTransform_o2p(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfObjects());
return m_objectVector[static_cast<size_t>(index)].second;
}
// ----------------------------------------------------------------------
void InteriorLayoutReaderWriter::Node::addObject(char const * const objectTemplateName, Transform const & transform_o2p)
{
FATAL(!objectTemplateName, (""));
m_objectVector.push_back(std::make_pair(PersistentCrcString(objectTemplateName, true), transform_o2p));
}
// ======================================================================
// PUBLIC InteriorLayoutReaderWriter
// ======================================================================
InteriorLayoutReaderWriter::InteriorLayoutReaderWriter() :
m_nodeMap(new NodeMap),
m_numberOfObjects(0)
{
}
// ----------------------------------------------------------------------
InteriorLayoutReaderWriter::~InteriorLayoutReaderWriter()
{
clear();
delete m_nodeMap;
}
// ----------------------------------------------------------------------
bool InteriorLayoutReaderWriter::load(const char* const fileName)
{
clear();
Iff iff;
if (iff.open(fileName, true))
{
load(iff);
return true;
}
return false;
}
// ----------------------------------------------------------------------
bool InteriorLayoutReaderWriter::save(const char* const fileName) const
{
Iff iff(1024);
save(iff);
return iff.write(fileName, true);
}
// ----------------------------------------------------------------------
CrcString const & InteriorLayoutReaderWriter::getFileName() const
{
return m_fileName;
}
// ----------------------------------------------------------------------
int InteriorLayoutReaderWriter::getNumberOfCellNames() const
{
return static_cast<int>(m_nodeMap->size());
}
// ----------------------------------------------------------------------
CrcString const & InteriorLayoutReaderWriter::getCellName(int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfCellNames());
NodeMap::iterator iter = m_nodeMap->begin();
for (int i = 0; i < index; ++i, ++iter)
;
return *iter->first;
}
// ----------------------------------------------------------------------
bool InteriorLayoutReaderWriter::hasCellName(CrcString const & cellName) const
{
return m_nodeMap->find(&cellName) != m_nodeMap->end();
}
// ----------------------------------------------------------------------
int InteriorLayoutReaderWriter::getNumberOfObjects(CrcString const & cellName) const
{
NodeMap::iterator iter = m_nodeMap->find(&cellName);
if (iter != m_nodeMap->end())
return static_cast<int>(iter->second->getNumberOfObjects());
return 0;
}
// ----------------------------------------------------------------------
CrcString const & InteriorLayoutReaderWriter::getObjectTemplateName(CrcString const & cellName, int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfObjects(cellName));
NodeMap::iterator iter = m_nodeMap->find(&cellName);
if (iter != m_nodeMap->end())
return iter->second->getObjectTemplateName(index);
DEBUG_FATAL(true, ("InteriorLayoutReaderWriter::getObjectTemplateName: %s does not have any objects in cells named %s", m_fileName.getString(), cellName.getString()));
return PersistentCrcString::empty;
}
// ----------------------------------------------------------------------
Transform const & InteriorLayoutReaderWriter::getTransform_o2p(CrcString const & cellName, int const index) const
{
VALIDATE_RANGE_INCLUSIVE_EXCLUSIVE(0, index, getNumberOfObjects(cellName));
NodeMap::iterator iter = m_nodeMap->find(&cellName);
if (iter != m_nodeMap->end())
return iter->second->getTransform_o2p(index);
DEBUG_FATAL(true, ("InteriorLayoutReaderWriter::getTransform_o2p: %s does not have any objects in cells named %s", m_fileName.getString(), cellName.getString()));
return Transform::identity;
}
// ----------------------------------------------------------------------
int InteriorLayoutReaderWriter::getNumberOfObjects() const
{
return m_numberOfObjects;
}
// ----------------------------------------------------------------------
void InteriorLayoutReaderWriter::getObjectTemplateNames(CrcStringVector & crcStringVector)
{
crcStringVector.reserve(static_cast<size_t>(m_numberOfObjects));
for (NodeMap::iterator iter = m_nodeMap->begin(); iter != m_nodeMap->end(); ++iter)
{
Node const * const node = iter->second;
for (int i = 0; i < node->getNumberOfObjects(); ++i)
{
CrcString const & objectTemplateName = node->getObjectTemplateName(i);
size_t j = 0;
for (; j < crcStringVector.size(); ++j)
if (*crcStringVector[j] == objectTemplateName)
break;
if (j == crcStringVector.size())
crcStringVector.push_back(&objectTemplateName);
}
}
}
// ----------------------------------------------------------------------
void InteriorLayoutReaderWriter::clear()
{
std::for_each(m_nodeMap->begin(), m_nodeMap->end(), PointerDeleterPairSecond());
m_nodeMap->clear();
m_numberOfObjects = 0;
}
// ----------------------------------------------------------------------
void InteriorLayoutReaderWriter::addObject(char const * const cellName, char const * const objectTemplateName, Transform const & transform_o2p)
{
Node * node = 0;
TemporaryCrcString const cellNameCrcString(cellName, true);
NodeMap::iterator iter = m_nodeMap->find(&cellNameCrcString);
if (iter != m_nodeMap->end())
node = iter->second;
else
{
node = new Node(cellName);
m_nodeMap->insert(std::make_pair(&node->getCellName(), node));
}
NOT_NULL(node);
node->addObject(objectTemplateName, transform_o2p);
++m_numberOfObjects;
}
// ======================================================================
// PUBLIC InteriorLayoutReaderWriter
// ======================================================================
void InteriorLayoutReaderWriter::load(Iff& iff)
{
if (iff.enterForm(TAG_INLY, true))
{
switch(iff.getCurrentName())
{
case TAG_0000:
load_0000(iff);
break;
default:
{
char tagBuffer [5];
ConvertTagToString(iff.getCurrentName(), tagBuffer);
char buffer [128];
iff.formatLocation(buffer, sizeof(buffer));
DEBUG_FATAL(true,("InteriorLayoutReaderWriter::load invalid version %s/%s", buffer, tagBuffer));
}
break;
}
iff.exitForm(TAG_INLY);
}
}
// ----------------------------------------------------------------------
void InteriorLayoutReaderWriter::load_0000(Iff& iff)
{
iff.enterForm(TAG_0000);
char objectTemplateName [512];
char cellName [512];
while (iff.getNumberOfBlocksLeft())
{
iff.enterChunk(TAG_NODE);
iff.read_string(objectTemplateName, 512);
iff.read_string(cellName, 512);
Transform const transform_o2p = iff.read_floatTransform();
addObject(cellName, objectTemplateName, transform_o2p);
iff.exitChunk(TAG_NODE);
}
iff.exitForm(TAG_0000);
}
// ----------------------------------------------------------------------
void InteriorLayoutReaderWriter::save(Iff& iff) const
{
iff.insertForm(TAG_INLY);
iff.insertForm(TAG_0000);
for (NodeMap::iterator iter = m_nodeMap->begin(); iter != m_nodeMap->end(); ++iter)
{
Node const * const node = iter->second;
for (int i = 0; i < node->getNumberOfObjects(); ++i)
{
iff.insertChunk(TAG_NODE);
iff.insertChunkString(node->getObjectTemplateName(i).getString());
iff.insertChunkString(node->getCellName().getString());
iff.insertChunkFloatTransform(node->getTransform_o2p(i));
iff.exitChunk(TAG_NODE);
}
}
iff.exitForm(TAG_0000);
iff.exitForm(TAG_INLY);
}
// ======================================================================
@@ -0,0 +1,76 @@
// ======================================================================
//
// InteriorLayoutReaderWriter.h
// asommers
//
// copyright 2002, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_InteriorLayoutReaderWriter_H
#define INCLUDED_InteriorLayoutReaderWriter_H
// ======================================================================
#include "sharedFoundation/PersistentCrcString.h"
class LessPointerComparator;
class Transform;
class Iff;
// ======================================================================
class InteriorLayoutReaderWriter
{
public:
InteriorLayoutReaderWriter ();
~InteriorLayoutReaderWriter ();
bool load (const char* fileName);
bool save (const char* fileName) const;
CrcString const & getFileName() const;
//-- reader interface
int getNumberOfCellNames() const;
CrcString const & getCellName(int index) const;
bool hasCellName(CrcString const & cellName) const;
int getNumberOfObjects(CrcString const & cellName) const;
CrcString const & getObjectTemplateName(CrcString const & cellName, int index) const;
Transform const & getTransform_o2p(CrcString const & cellName, int index) const;
//-- preload interface
int getNumberOfObjects() const;
typedef stdvector<CrcString const *>::fwd CrcStringVector;
void getObjectTemplateNames(CrcStringVector & crcStringVector);
//-- writer interface
void clear ();
void addObject(char const * cellName, char const * objectTemplateName, Transform const & transform_o2p);
private:
void load (Iff& iff);
void load_0000 (Iff& iff);
void save (Iff& iff) const;
private:
InteriorLayoutReaderWriter (const InteriorLayoutReaderWriter&);
InteriorLayoutReaderWriter& operator= (const InteriorLayoutReaderWriter&);
private:
PersistentCrcString m_fileName;
class Node;
typedef stdmap<CrcString const *, Node *, LessPointerComparator>::fwd NodeMap;
NodeMap * const m_nodeMap;
int m_numberOfObjects;
};
// ======================================================================
#endif
@@ -0,0 +1,112 @@
// ======================================================================
//
// LocalMachineOptionManager.cpp
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/LocalMachineOptionManager.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedUtility/OptionManager.h"
// ======================================================================
// LocalMachineOptionManagerNamespace
// ======================================================================
namespace LocalMachineOptionManagerNamespace
{
char const * const cms_fileName = "local_machine_options.iff";
bool ms_installed;
OptionManager * ms_optionManager;
}
using namespace LocalMachineOptionManagerNamespace;
// ======================================================================
// STATIC PUBLIC LocalMachineOptionManager
// ======================================================================
void LocalMachineOptionManager::install ()
{
DEBUG_FATAL (ms_installed, ("LocalMachineOptionManager::install: already installed"));
ms_installed = true;
ms_optionManager = new OptionManager;
ms_optionManager->load (cms_fileName);
ExitChain::add (remove, "LocalMachineOptionManager::remove");
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::remove ()
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::remove: not installed"));
ms_installed = false;
delete ms_optionManager;
ms_optionManager = 0;
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::save ()
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::save: not installed"));
ms_optionManager->save (cms_fileName);
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::registerOption (bool & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::registerOption (float & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::registerOption (int & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::registerOption (std::string & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
void LocalMachineOptionManager::registerOption (Unicode::String & variable, char const * const section, char const * const name, const int version)
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::registerOption: not installed"));
ms_optionManager->registerOption (variable, section, name, version);
}
// ----------------------------------------------------------------------
float LocalMachineOptionManager::findFloat(char const * const section, char const * const name, float const defaultValue)
{
DEBUG_FATAL (!ms_installed, ("LocalMachineOptionManager::findFloat: not installed"));
return ms_optionManager->findFloat (section, name, defaultValue);
}
// ======================================================================
@@ -0,0 +1,42 @@
// ======================================================================
//
// LocalMachineOptionManager.h
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_LocalMachineOptionManager_H
#define INCLUDED_LocalMachineOptionManager_H
// ======================================================================
class LocalMachineOptionManager
{
public:
static void install ();
static void remove ();
static void save ();
static void registerOption (bool & variable, char const * section, char const * name, const int version = 0);
static void registerOption (float & variable, char const * section, char const * name, const int version = 0);
static void registerOption (int & variable, char const * section, char const * name, const int version = 0);
static void registerOption (std::string & variable, char const * section, char const * name, const int version = 0);
static void registerOption (Unicode::String & variable, char const * section, char const * name, const int version = 0);
static float findFloat(char const * section, char const * name, float defaultValue);
private:
LocalMachineOptionManager ();
~LocalMachineOptionManager ();
LocalMachineOptionManager (LocalMachineOptionManager const &);
LocalMachineOptionManager & operator= (LocalMachineOptionManager const &);
};
// ======================================================================
#endif
@@ -0,0 +1,182 @@
// Location.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/Location.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedFoundation/CrcStringTable.h"
#include <string>
//-----------------------------------------------------------------------
namespace LocationNamespace
{
CrcStringTable * s_planetCrcStringTable = 0;
struct TableAllocator
{
TableAllocator();
~TableAllocator();
};
TableAllocator::TableAllocator()
{
if(! s_planetCrcStringTable)
s_planetCrcStringTable = new CrcStringTable("misc/planet_crc_string_table.iff");
}
TableAllocator::~TableAllocator()
{
delete s_planetCrcStringTable;
}
}
using namespace LocationNamespace;
//-----------------------------------------------------------------------
Location::Location() :
m_coordinates(),
m_cell(),
m_sceneIdCrc()
{
static TableAllocator t;
}
//-----------------------------------------------------------------------
Location::Location(const Location & source) :
m_coordinates(source.m_coordinates),
m_cell(source.m_cell),
m_sceneIdCrc(source.m_sceneIdCrc)
{
}
//-----------------------------------------------------------------------
Location::Location(const Vector & coordinates, const NetworkId & cell, unsigned int sceneIdCrc) :
m_coordinates(coordinates),
m_cell(cell),
m_sceneIdCrc(sceneIdCrc)
{
}
//-----------------------------------------------------------------------
Location::~Location()
{
}
//-----------------------------------------------------------------------
Location & Location::operator = (const Location & rhs)
{
if(&rhs != this)
{
m_coordinates = rhs.m_coordinates;
m_cell = rhs.m_cell;
m_sceneIdCrc = rhs.m_sceneIdCrc;
}
return *this;
}
//-----------------------------------------------------------------------
bool Location::operator != (const Location & rhs) const
{
return (m_coordinates != rhs.m_coordinates || m_cell != rhs.m_cell || m_sceneIdCrc != rhs.m_sceneIdCrc);
}
//-----------------------------------------------------------------------
bool Location::operator < (const Location & rhs) const
{
if (m_sceneIdCrc != rhs.m_sceneIdCrc)
return m_sceneIdCrc < rhs.m_sceneIdCrc;
if (m_cell != rhs.m_cell)
return m_cell < rhs.m_cell;
return m_coordinates.x < rhs.m_coordinates.x;
}
//-----------------------------------------------------------------------
const char * const Location::getSceneNameByCrc(unsigned int crc)
{
return s_planetCrcStringTable->lookUp(crc).getString();
}
//-----------------------------------------------------------------------
unsigned int Location::getCrcBySceneName(const char * const name)
{
return s_planetCrcStringTable->lookUp(name).getCrc();
}
//-----------------------------------------------------------------------
unsigned int Location::getCrcBySceneName(const std::string & name)
{
return getCrcBySceneName(name.c_str());
}
//-----------------------------------------------------------------------
const Vector & Location::getCoordinates() const
{
return m_coordinates;
}
//-----------------------------------------------------------------------
const NetworkId & Location::getCell() const
{
return m_cell;
}
//-----------------------------------------------------------------------
unsigned int Location::getSceneIdCrc() const
{
return m_sceneIdCrc;
}
//-----------------------------------------------------------------------
const char * const Location::getSceneId() const
{
return getSceneNameByCrc(m_sceneIdCrc);
}
//-----------------------------------------------------------------------
void Location::setCoordinates(const Vector & coordinates)
{
m_coordinates = coordinates;
}
//-----------------------------------------------------------------------
void Location::setCell(const NetworkId & cell)
{
m_cell = cell;
}
//-----------------------------------------------------------------------
void Location::setSceneIdCrc(unsigned int crc)
{
m_sceneIdCrc = crc;
}
//-----------------------------------------------------------------------
void Location::setSceneId(const char * const name)
{
m_sceneIdCrc = getCrcBySceneName(name);
}
//-----------------------------------------------------------------------
@@ -0,0 +1,52 @@
// Location.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_Location_H
#define _INCLUDED_Location_H
//-----------------------------------------------------------------------
#include "sharedMath/Vector.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedUtility/LocationArchive.h"
//-----------------------------------------------------------------------
// WARNING: If you edit this class, you must also edit the persistence functions for it (SwgSnapshot.cpp)
class Location
{
public:
Location();
Location(const Vector & coordinates, const NetworkId & cell, unsigned int sceneIdCrc);
Location & operator = (const Location & rhs);
Location(const Location & source);
~Location();
bool operator != (const Location & rhs) const;
bool operator < (const Location & rhs) const;
const Vector & getCoordinates () const;
const NetworkId & getCell () const;
unsigned int getSceneIdCrc () const;
const char * const getSceneId () const;
static const char * const getSceneNameByCrc (unsigned int crc);
static unsigned int getCrcBySceneName (const char * const name);
static unsigned int getCrcBySceneName (const std::string & name);
void setCoordinates (const Vector & coordinates);
void setCell (const NetworkId & cell);
void setSceneIdCrc (unsigned int crc);
void setSceneId (const char * const sceneId);
private:
friend void Archive::get(Archive::ReadIterator &, Location &);
Vector m_coordinates;
NetworkId m_cell;
unsigned int m_sceneIdCrc;
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_Location_H
@@ -0,0 +1,34 @@
// LocationArchive.cpp
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/LocationArchive.h"
#include "Archive/Archive.h"
#include "sharedUtility/Location.h"
#include "sharedMathArchive/VectorArchive.h"
#include "sharedFoundation/NetworkIdArchive.h"
//-----------------------------------------------------------------------
namespace Archive
{
void get (Archive::ReadIterator & source, Location & target)
{
get(source, target.m_coordinates);
get(source, target.m_cell);
get(source, target.m_sceneIdCrc);
}
void put (ByteStream & target, const Location & source)
{
put(target, source.getCoordinates());
put(target, source.getCell());
put(target, source.getSceneIdCrc());
}
}
@@ -0,0 +1,23 @@
// LocationArchive.h
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_LocationArchive_H
#define _INCLUDED_LocationArchive_H
//-----------------------------------------------------------------------
class Location;
namespace Archive
{
class ReadIterator;
class ByteStream;
void get (Archive::ReadIterator & source, Location & target);
void put (ByteStream & target, const Location & source);
}
//-----------------------------------------------------------------------
#endif // _INCLUDED_LocationArchive_H
@@ -0,0 +1,366 @@
// ======================================================================
//
// LocationManager.cpp
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/LocationManager.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedFoundation/MemoryBlockManager.h"
#include "sharedFoundation/MemoryBlockManagerMacros.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedFoundation/PointerDeleter.h"
#include "sharedMath/Rectangle2d.h"
#include "sharedMath/SphereTree.h"
#include "sharedMath/Vector2d.h"
#include "sharedUtility/BakedTerrain.h"
#include "sharedUtility/BakedTerrainReader.h"
#include "sharedUtility/ConfigSharedUtility.h"
#include <algorithm>
#include <map>
#include <string>
// ======================================================================
// LocationManagerNamespace
// ======================================================================
namespace LocationManagerNamespace
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class Node
{
MEMORY_BLOCK_MANAGER_INTERFACE_WITHOUT_INSTALL;
public:
static void install ();
static void remove ();
public:
explicit Node (NetworkId const & networkId);
~Node ();
Sphere const getSphere () const;
void setSphere (int x, int z, int radius);
SpatialSubdivisionHandle * getSpatialSubdivisionHandle ();
void setSpatialSubdivisionHandle (SpatialSubdivisionHandle * spatialSubdivisionHandle);
private:
Node ();
Node (Node const & rhs);
Node & operator= (Node const & rhs);
private:
NetworkId m_networkId;
int m_x;
int m_z;
int m_radius;
SpatialSubdivisionHandle * m_spatialSubdivisionHandle;
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class NodeSphereExtentAccessor: public BaseSphereTreeAccessor<Node *, NodeSphereExtentAccessor>
{
public:
static Sphere const getExtent (Node const * const node)
{
return node ? node->getSphere () : Sphere::zero;
}
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
typedef SphereTree<Node *, NodeSphereExtentAccessor> NodeSphereTree;
typedef std::vector<Node *> NodeVector;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string ms_planetName;
NodeSphereTree ms_nodeSphereTree;
typedef std::map<NetworkId, Node *> NodeMap;
NodeMap ms_nodeMap;
BakedTerrain * ms_bakedTerrain;
typedef std::vector<std::pair<int, int> > OffsetList;
OffsetList ms_offsetList;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void remove ();
bool intersectsObject (float x, float z, float radius);
void clearSphereTree (NodeSphereTree & sphereTree);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
using namespace LocationManagerNamespace;
// ======================================================================
// STATIC PUBLIC LocationManager::Node
// ======================================================================
MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITHOUT_INSTALL (Node, true, 0, 0, 0);
// ----------------------------------------------------------------------
void Node::install ()
{
installMemoryBlockManager ();
}
// ----------------------------------------------------------------------
void Node::remove ()
{
removeMemoryBlockManager ();
}
// ======================================================================
// PUBLIC LocationManagerNamespace::Node
// ======================================================================
Node::Node (NetworkId const & networkId) :
m_networkId (networkId),
m_x (0),
m_z (0),
m_radius (0),
m_spatialSubdivisionHandle (0)
{
}
// ----------------------------------------------------------------------
Node::~Node ()
{
m_spatialSubdivisionHandle = 0;
}
// ----------------------------------------------------------------------
Sphere const Node::getSphere () const
{
return Sphere (Vector (static_cast<float> (m_x), 0.f, static_cast<float> (m_z)), static_cast<float> (m_radius));
}
// ----------------------------------------------------------------------
void Node::setSphere (int const x, int const z, int const radius)
{
m_x = x;
m_z = z;
m_radius = radius;
}
// ----------------------------------------------------------------------
SpatialSubdivisionHandle * Node::getSpatialSubdivisionHandle ()
{
return m_spatialSubdivisionHandle;
}
// ----------------------------------------------------------------------
void Node::setSpatialSubdivisionHandle (SpatialSubdivisionHandle * const spatialSubdivisionHandle)
{
m_spatialSubdivisionHandle = spatialSubdivisionHandle;
}
// ======================================================================
// STATIC PUBLIC LocationManager
// ======================================================================
void LocationManager::install ()
{
Node::install ();
ExitChain::add (remove, "LocationManager::remove");
}
// ----------------------------------------------------------------------
void LocationManager::setPlanetName (char const * const planetName)
{
ms_planetName = planetName;
char fileName [256];
sprintf (fileName, "terrain/%s.trn", planetName);
if (ms_bakedTerrain)
delete ms_bakedTerrain;
ms_bakedTerrain = BakedTerrainReader::create (fileName);
}
// ----------------------------------------------------------------------
void LocationManager::updateObject (NetworkId const & networkId, int const x, int const z, int const radius)
{
Node * node = 0;
NodeMap::iterator iter = ms_nodeMap.find (networkId);
if (iter == ms_nodeMap.end ())
{
//-- add
node = new Node (networkId);
IGNORE_RETURN (ms_nodeMap.insert (std::make_pair (networkId, node)));
}
else
{
//-- update
node = NON_NULL (iter->second);
ms_nodeSphereTree.removeObject (node->getSpatialSubdivisionHandle ());
}
node->setSphere (x, z, radius);
node->setSpatialSubdivisionHandle (ms_nodeSphereTree.addObject (node));
}
// ----------------------------------------------------------------------
void LocationManager::removeObject (NetworkId const & networkId)
{
NodeMap::iterator iter = ms_nodeMap.find (networkId);
if (iter != ms_nodeMap.end ())
{
Node * const node = NON_NULL (iter->second);
ms_nodeSphereTree.removeObject (node->getSpatialSubdivisionHandle ());
delete node;
ms_nodeMap.erase (iter);
}
}
// ----------------------------------------------------------------------
bool LocationManager::requestLocation (float const searchX, float const searchZ, float const searchRadius, float const locationRadius, bool const checkWater, bool const checkSlope, float & resultX, float & resultZ)
{
Rectangle2d const searchArea (searchX - searchRadius, searchZ - searchRadius, searchX + searchRadius, searchZ + searchRadius);
int const chunkSize = ConfigSharedUtility::getChunkSize();
ms_offsetList.clear ();
{
//-- generate the offset list
int const logicalWidth = static_cast<int> (searchArea.getWidth () / chunkSize);
int const logicalHeight = static_cast<int> (searchArea.getHeight () / chunkSize);
int const logicalRadius = static_cast<int> (searchRadius / chunkSize);
int const centerX = logicalWidth / 2;
int const centerZ = logicalHeight / 2;
for (int i = 0; i < logicalWidth; ++i)
for (int j = 0; j < logicalHeight; ++j)
{
int const logicalX = i - centerX;
int const logicalZ = j - centerZ;
if (sqr (logicalX) + sqr (logicalZ) < sqr (logicalRadius))
ms_offsetList.push_back (std::make_pair (logicalX, logicalZ));
}
//-- shuffle offset list to randomize rasterization
std::random_shuffle (ms_offsetList.begin (), ms_offsetList.end ());
}
bool found = false;
{
for (OffsetList::iterator iter = ms_offsetList.begin (); iter != ms_offsetList.end (); ++iter)
{
//-- start in the upper left corner of the search area
Rectangle2d currentArea (0.f, 0.f, locationRadius * 2.f, locationRadius * 2.f);
currentArea.translate (static_cast<float> (iter->first * chunkSize) + searchX, static_cast<float> (iter->second * chunkSize) + searchZ);
//-- check the current area for water
if (checkWater && ms_bakedTerrain && ms_bakedTerrain->getWater (currentArea))
continue;
//-- check the current area for slope
if (checkSlope && ms_bakedTerrain && ms_bakedTerrain->getSlope (currentArea))
continue;
//-- check the current area for objects
float const x = currentArea.getCenter ().x;
float const z = currentArea.getCenter ().y;
if (intersectsObject (x, z, locationRadius))
continue;
//-- we found a location
found = true;
resultX = x;
resultZ = z;
}
}
return found;
}
// ======================================================================
// LocationManagerNamespace
// ======================================================================
void LocationManagerNamespace::remove ()
{
//-- delete the baked terrain
if (ms_bakedTerrain)
{
delete ms_bakedTerrain;
ms_bakedTerrain = 0;
}
//-- clear the sphere tree
clearSphereTree (ms_nodeSphereTree);
//-- clear the node map
IGNORE_RETURN (std::for_each (ms_nodeMap.begin (), ms_nodeMap.end (), PointerDeleterPairSecond ()));
ms_nodeMap.clear ();
Node::remove ();
}
// ----------------------------------------------------------------------
bool LocationManagerNamespace::intersectsObject (float const x, float const z, float const radius)
{
NodeVector result;
ms_nodeSphereTree.findInRange (Vector (x, 0.f, z), radius, result);
return !result.empty ();
}
// ----------------------------------------------------------------------
void LocationManagerNamespace::clearSphereTree (NodeSphereTree & sphereTree)
{
typedef std::vector<std::pair<Node *, Sphere> > NodeSphereList;
NodeSphereList nodeSphereList;
sphereTree.dumpSphereTreeObjs (nodeSphereList);
NodeSphereList::const_iterator end = nodeSphereList.end ();
for (NodeSphereList::const_iterator iter = nodeSphereList.begin (); iter != end; ++iter)
{
Node * const node = iter->first;
if (node)
{
sphereTree.removeObject (node->getSpatialSubdivisionHandle ());
node->setSpatialSubdivisionHandle (0);
delete node;
}
}
}
// ======================================================================
@@ -0,0 +1,35 @@
// ======================================================================
//
// LocationManager.h
// asommers
//
// copyright 2003, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_LocationManager_H
#define INCLUDED_LocationManager_H
// ======================================================================
class NetworkId;
// ======================================================================
class LocationManager
{
public:
static void install ();
static void setPlanetName (char const * planetName);
static void updateObject (NetworkId const & networkId, int x, int z, int radius);
static void removeObject (NetworkId const & networkId);
static bool requestLocation (float searchX, float searchZ, float searchRadius, float locationRadius, bool checkWater, bool checkSlope, float & resultX, float & resultZ);
};
// ======================================================================
#endif
@@ -0,0 +1,650 @@
//
// FileName.h
// asommers 5-26-99
//
// copyright 1999, bootprint entertainment
//
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/NameGenerator.h"
#include "sharedRandom/Random.h"
#include "sharedUtility/DataTable.h"
#include "sharedUtility/DataTableManager.h"
#include "UnicodeUtils.h"
#include <algorithm>
#include <set>
#include <stdio.h>
//====================================================================
NameGenerator::NameGenerator(const std::string &i_language, const std::string &directory)
{
std::string datatablePath("datatables/" + directory + "/");
m_initialized = false;
if (i_language.empty())
return;
DataTable * vowelTable = DataTableManager::getTable(datatablePath+"vowels.iff", true);
DataTable * consonantTable = DataTableManager::getTable(datatablePath+"consonants.iff", true);
DataTable * specialTable = DataTableManager::getTable(datatablePath+"special.iff", true);
DataTable * professionPatternTable = DataTableManager::getTable(datatablePath+"profession_patterns.iff", true);
DataTable * professionTable = DataTableManager::getTable(datatablePath+"profession.iff", true);
DataTable * ruleTable = DataTableManager::getTable(datatablePath+"rules.iff", true);
if (!ruleTable ||
!professionTable ||
!professionPatternTable ||
!specialTable ||
!consonantTable ||
!vowelTable)
{
WARNING_STRICT_FATAL(true, ("Couldn't open a naming data table with path %s language %s\n", datatablePath.c_str(), i_language.c_str()));
return;
}
int ruleRow = findRow(ruleTable, "id", i_language);
if (ruleRow < 0)
{
WARNING(true, ("Couldn't find language [%s] in rule table path %s\n", i_language.c_str(), datatablePath.c_str()));
return;
}
pushNameTemplate(ruleTable, ruleRow, "fname_");
pushNameTemplate(ruleTable, ruleRow, "lname_");
loadColumn(m_initialConsonants, consonantTable, i_language, "placement", 'b');
loadColumn(m_medialConsonants, consonantTable, i_language, "placement", 'm');
loadColumn(m_finalConsonants, consonantTable, i_language, "placement", 'e');
loadColumn(m_vowels, vowelTable, i_language);
loadColumn(m_specialSyllables, specialTable, i_language);
loadColumn(m_professionPatterns, professionPatternTable, i_language);
// now extract all of the word types from profession patterns
std::vector<OddsValue>::iterator ppi;
bool inLiteral = false;
for (ppi = m_professionPatterns.begin(); ppi != m_professionPatterns.end(); ++ppi)
{
const std::string &value = ppi->value;
std::string::const_iterator c;
for (c=value.begin(); c!=value.end(); ++c)
{
if (*c == '\\') // skip literals
{
inLiteral = true;
}
else if (*c == '*') // skip
{
}
else
{
if (!inLiteral)
{
std::map<char, std::vector<OddsValue> *>::iterator wordIter = m_professions.find(*c);
if (wordIter == m_professions.end())
{
m_professions[*c] = new std::vector<OddsValue>();
loadColumn(*m_professions[*c], professionTable, i_language, "type", *c);
}
}
inLiteral = false;
}
}
}
if (!m_nameTemplates.empty())
{
m_initialized = true;
}
}
//--------------------------------------------------------------------
NameGenerator::~NameGenerator()
{
std::map<char, std::vector<OddsValue> * >::iterator i;
for (i=m_professions.begin(); i!=m_professions.end(); ++i)
{
delete i->second;
}
m_professions.clear();
}
//--------------------------------------------------------------------
Unicode::String NameGenerator::generateRandomName() const
{
if (!m_initialized)
return Unicode::String();
std::vector<NameTemplate>::const_iterator i;
bool first = true;
std::string result;
for (i=m_nameTemplates.begin(); i!=m_nameTemplates.end(); ++i)
{
if (Random::randomReal() < i->m_odds)
{
if (!first)
{
result += " ";
}
result += generateSingleName(*i);
first = false;
}
}
if (first)
{
result = generateSingleName(m_nameTemplates.front());
}
return Unicode::narrowToWide(capitalizeName(result));
}
//--------------------------------------------------------------------
int NameGenerator::findRow(DataTable * table, const std::string &column, const std::string &value)
{
int i;
for (i=0; i<table->getNumRows(); ++i)
{
if (value == table->getStringValue(column, i))
{
return i;
}
}
return -1;
}
//--------------------------------------------------------------------
void NameGenerator::pushNameTemplate(DataTable * table, int row, const std::string &prefix)
{
float odds = table->getIntValue(prefix+"chance", row) / 100.f; // don't convert this to *0.01f, we need to insure that int(100)/100.0f equals exactly 1.
if (odds == 0)
return;
NameTemplate temp;
temp.m_odds = odds;
temp.m_chanceProfession = table->getIntValue(prefix+"chance_profession", row) * 0.01f;
temp.m_syllablesMin = table->getIntValue(prefix+"syllables_min", row);
temp.m_syllablesMax = table->getIntValue(prefix+"syllables_max", row);
temp.m_charsMin = table->getIntValue(prefix+"chars_min", row);
temp.m_charsMax = table->getIntValue(prefix+"chars_max", row);
temp.m_specialCharChance = table->getIntValue(prefix+"special_char_chance", row) * 0.01f;
temp.m_specialChars = table->getStringValue(prefix+"special_char", row);
temp.m_specialCharMax = table->getIntValue(prefix+"special_char_max", row);
temp.m_chanceBeginsSpecial = table->getIntValue(prefix+"chance_begins_special", row) * 0.01f;
temp.m_chanceMedialSpecial = table->getIntValue(prefix+"chance_medial_special", row) * 0.01f;
temp.m_chanceEndsSpecial = table->getIntValue(prefix+"chance_ends_special", row) * 0.01f;
temp.m_maxSpecialSyllables = table->getIntValue(prefix+"max_special_syllables", row);
m_nameTemplates.push_back(temp);
}
//--------------------------------------------------------------------
std::string NameGenerator::generateSingleName(const NameTemplate &nt) const
{
if (Random::randomReal() < nt.m_chanceProfession)
return generateProfessionName(nt);
else
return generateRandomName(nt);
}
//--------------------------------------------------------------------
std::string NameGenerator::generateRandomName(const NameTemplate &nt) const
{
for (;;)
{
int syllables = nt.m_syllablesMin;
while (syllables < nt.m_syllablesMax)
{
float syllableChance = 0.6f - syllables / (nt.m_syllablesMax*2.0f);
if (Random::randomReal() > syllableChance)
break;
++syllables;
}
bool nextSyllableIsFirst = true;
std::string result;
int specialCharCount = 0;
std::set<std::string> selectedSpecialSyllables;
int i;
for (i=0; i<syllables; ++i)
{
std::string oldResult(result);
bool firstSyllable = nextSyllableIsFirst;
nextSyllableIsFirst = false;
bool finalSyllable = (i == syllables - 1);
bool appendSpecial = false;
if (!finalSyllable)
{
if (specialCharCount < nt.m_specialCharMax && Random::randomReal() < nt.m_specialCharChance)
{
appendSpecial = true;
finalSyllable = true;
nextSyllableIsFirst = true;
}
}
float specialSyllableChance = nt.m_chanceMedialSpecial;
if (firstSyllable)
specialSyllableChance = nt.m_chanceBeginsSpecial;
else if (finalSyllable)
specialSyllableChance = nt.m_chanceEndsSpecial;
if (Random::randomReal() < specialSyllableChance && (int)selectedSpecialSyllables.size() < nt.m_maxSpecialSyllables)
{
for (;;)
{
std::string specialSyllable = selectSpecialSyllable();
if (selectedSpecialSyllables.find(specialSyllable) != selectedSpecialSyllables.end())
continue;
result = appendSyllable(result, specialSyllable);
selectedSpecialSyllables.insert(specialSyllable);
break;
}
}
else
{
std::string syllablePattern;
float syllableSelect = Random::randomReal();
if (syllableSelect < 0.40f)
{
syllablePattern = "cv";
}
else if (syllableSelect < 0.80f)
{
syllablePattern = "vc";
}
else
{
syllablePattern = "v";
}
std::string::const_iterator syllIter;
std::string syllable;
for (syllIter = syllablePattern.begin(); syllIter != syllablePattern.end(); ++syllIter)
{
if (*syllIter == 'c')
{
if (firstSyllable && syllIter == syllablePattern.begin())
{
syllable += selectInitialConsonant();
}
else if (finalSyllable && (syllIter+1) == syllablePattern.end())
{
syllable += selectFinalConsonant();
}
else
{
syllable += selectMedialConsonant();
}
}
else
{
syllable += selectVowel();
}
}
result = appendSyllable(result, syllable);
}
if (result == oldResult)
--i; // it's still alright to append because if the endings matched, the old ending must have been a valid final consonant.
// append a special character
if (appendSpecial && !result.empty())
{
int s = nt.m_specialChars.size();
char toInsert = nt.m_specialChars[Random::random(s-1)];
result = appendSyllable(result, std::string(1, toInsert));
++specialCharCount;
}
}
// now do sanity checks
// retry if the length is bad
int resultSize = static_cast<int>(result.size());
if (resultSize < nt.m_charsMin)
continue;
else if (resultSize > nt.m_charsMax)
continue;
// continue if we have a lonely special syllable
if (getFragmentType(result) == kSpecial)
continue;
// now capitalize
return result;
}
}
//--------------------------------------------------------------------
std::string NameGenerator::generateProfessionName(const NameTemplate &nt) const
{
std::string professionPattern = selectProfessionPattern();
if (professionPattern.empty())
return std::string();
std::set<std::string> usedRoots;
std::string result;
std::string::const_iterator i;
bool append = false;
for (i=professionPattern.begin(); i!=professionPattern.end(); ++i)
{
if (*i == '\\')
{
++i;
if (i != professionPattern.end())
{
result += *i;
}
}
else if (*i == '*')
{
result = appendSyllable(result, generateRandomName(nt));
}
else
{
for (;;)
{
std::string profession, root;
profession = selectProfession(*i, &root);
if (!root.empty() && usedRoots.find(root) != usedRoots.end())
continue;
if (append)
{
result = appendSyllable(result, profession);
append = false;
}
else
{
result += profession;
}
usedRoots.insert(root);
break;
}
}
}
return result;
}
//--------------------------------------------------------------------
void NameGenerator::balanceOdds(std::vector<OddsValue>::iterator begin, std::vector<OddsValue>::iterator end)
{
std::sort(begin, end);
std::vector<OddsValue>::iterator i;
float total = 0;
for (i=begin; i!=end; ++i)
total += i->odds;
float accum = 0;
for (i=begin; i!=end; ++i)
{
float odds = i->odds / total;
accum += odds;
i->odds = accum;
}
// correct rounding errors
if (end > begin)
(end-1)->odds = 1.0f;
}
//--------------------------------------------------------------------
std::string NameGenerator::selectRandomFrom(std::vector<OddsValue>::const_iterator begin, std::vector<OddsValue>::const_iterator end, std::string * extra) const
{
if (begin == end)
{
if (extra)
*extra = std::string();
return std::string();
}
float rr = Random::randomReal();
FATAL(rr >= 1.0f, ("randomReal returned an invalid random number %g\n", rr));
std::vector<OddsValue>::const_iterator i = std::lower_bound(begin, end, rr, OddsValue::findFloat());
/*
std::vector<OddsValue>::const_iterator i;
for (i=begin; i!=end; ++i)
{
if (rr < i->odds)
{
if (extra)
*extra = i->extra;
return i->value;
}
rr -= i->odds;
}
// just in case of rounding errors
return (end-1)->value;
*/
if (extra)
*extra = i->extra;
return i->value;
}
//--------------------------------------------------------------------
std::string NameGenerator::capitalizeName(const std::string &result) const
{
std::string capitalizedResult;
std::string::const_iterator capIter;
bool capNext = true;
for (capIter = result.begin(); capIter != result.end(); ++capIter)
{
if (capNext)
{
capitalizedResult += (char)toupper(*capIter);
}
else
{
capitalizedResult += *capIter;
}
if (*capIter == ' ')
{
capNext = true;
}
else if (*capIter == '\'' || *capIter == '-')
{
capNext = Random::randomReal() > 0.5f;
}
else
{
capNext = false;
}
}
return capitalizedResult;
}
//--------------------------------------------------------------------
void NameGenerator::loadColumn(std::vector<OddsValue> &result, DataTable * source, const std::string &i_language)
{
int rows = source->getNumRows();
int languageColumnIndex = source->findColumnNumber(i_language);
int i;
for (i=0; i<rows; ++i)
{
std::string value = source->getStringValue(0, i);
int odds = source->getIntValue(languageColumnIndex, i);
if (odds == 0)
continue;
OddsValue temp;
temp.value = value;
temp.odds = (float)odds;
result.push_back(temp);
}
balanceOdds(result.begin(), result.end());
}
//--------------------------------------------------------------------
void NameGenerator::loadColumn(std::vector<OddsValue> &result, DataTable * source, const std::string &i_language, const std::string &maskColumn, const char maskChar)
{
int rows = source->getNumRows();
int maskColumnIndex = source->findColumnNumber(maskColumn);
int languageColumnIndex = source->findColumnNumber(i_language);
int i;
for (i=0; i<rows; ++i)
{
std::string value = source->getStringValue(0, i);
int odds = source->getIntValue(languageColumnIndex, i);
if (odds == 0)
continue;
std::string mask = source->getStringValue(maskColumnIndex, i);
if (mask.find(maskChar) == std::string::npos)
continue;
OddsValue temp;
temp.value = value;
temp.odds = (float)odds;
if (maskColumnIndex >= 2)
{
temp.extra = source->getStringValue(1, i);
}
result.push_back(temp);
}
balanceOdds(result.begin(), result.end());
}
//--------------------------------------------------------------------
std::string NameGenerator::appendSyllable(const std::string &left, const std::string &right) const
{
if (left.empty())
return right;
// now we try to merge/simplify repeated letters. If there are too many repeats, we insert
// a remedial vowel or consonant to try and make the word more pronounceable
// grab the longest ending vowel or consonant string from left
std::string::const_iterator l = left.end();
eFragmentType leftFragmentType = kMixed;
std::string leftFragment;
while (l != left.begin())
{
--l;
std::string leftEnd(l, left.end());
eFragmentType fragment = getFragmentType(leftEnd);
if (fragment == kMixed || fragment == kSpecial)
break;
leftFragment = leftEnd;
leftFragmentType = fragment;
}
eFragmentType rightFragmentType = kMixed;
std::string rightFragment;
std::string::const_iterator r = right.begin();
while (r != right.end())
{
++r;
std::string rightBegin(right.begin(), r);
eFragmentType fragment = getFragmentType(rightBegin);
if (fragment == kMixed || fragment == kSpecial)
break;
rightFragment = rightBegin;
rightFragmentType = fragment;
}
if (leftFragmentType != rightFragmentType)
return left + right;
if (leftFragment == rightFragment)
return left;
if (leftFragmentType == kConsonant)
return left + selectVowel() + right;
else
return left + selectMedialConsonant() + right;
}
//--------------------------------------------------------------------
NameGenerator::eFragmentType NameGenerator::getFragmentType(const std::string &test) const
{
if (hasString(m_vowels, test))
return kVowel;
if (hasString(m_initialConsonants, test))
return kConsonant;
if (hasString(m_medialConsonants, test))
return kConsonant;
if (hasString(m_finalConsonants, test))
return kConsonant;
if (hasString(m_specialSyllables, test))
return kSpecial;
return kMixed;
}
//--------------------------------------------------------------------
bool NameGenerator::hasString(const std::vector<OddsValue> &array, const std::string &test) const
{
std::vector<OddsValue>::const_iterator i;
i = std::lower_bound(array.begin(), array.end(), test, OddsValue::findString());
if (i == array.end())
return false;
if (i->value != test)
return false;
return true;
}
//--------------------------------------------------------------------
bool NameGenerator::verifyName(const Unicode::String &name) const
{
size_t minNameCount = 0;
std::vector<NameTemplate>::const_iterator i;
for (i = m_nameTemplates.begin(); i!=m_nameTemplates.end(); ++i)
{
if (i->m_odds >= 1.0f)
{
++minNameCount;
}
}
int pos=0;
size_t nameindex = 0;
for (;;)
{
if (nameindex >= m_nameTemplates.size())
return false;
int newpos = name.find(' ', pos);
int namelength = newpos - pos;
if (newpos == int(Unicode::String::npos))
{
namelength = name.size() - pos;
}
if (namelength < m_nameTemplates[nameindex].m_charsMin)
return false;
if (namelength > m_nameTemplates[nameindex].m_charsMax)
return false;
pos = newpos + 1;
++nameindex;
if (newpos == int(Unicode::String::npos))
{
if (nameindex < minNameCount)
return false;
else
return true;
}
}
return true; // just in case, should always return from the newpos == npos test
}
//====================================================================
@@ -0,0 +1,165 @@
//
// FileName.h
// asommers 5-26-99
//
// copyright 1999, bootprint entertainment
//
#ifndef INCLUDED_NameGenerator_H
#define INCLUDED_NameGenerator_H
#include <vector>
#include <map>
#include <string>
class DataTable;
//====================================================================
class NameGenerator
{
public:
NameGenerator(const std::string &language, const std::string &directory);
virtual ~NameGenerator();
virtual bool verifyName(const Unicode::String &name) const;
virtual Unicode::String generateRandomName() const;
bool getInitialized() const;
private:
bool m_initialized;
struct NameTemplate
{
float m_odds;
float m_chanceProfession;
int m_syllablesMin;
int m_syllablesMax;
int m_charsMin;
int m_charsMax;
float m_specialCharChance;
std::string m_specialChars;
int m_specialCharMax;
float m_chanceBeginsSpecial;
float m_chanceMedialSpecial;
float m_chanceEndsSpecial;
int m_maxSpecialSyllables;
};
std::vector<NameTemplate> m_nameTemplates;
struct OddsValue
{
std::string value;
float odds;
std::string extra;
bool operator <(const OddsValue &o) const { return value < o.value; }
struct findFloat { bool operator ()(const OddsValue &o, float f) const { return o.odds < f; } };
struct findString { bool operator ()(const OddsValue &o, const std::string &f) const { return o.value < f; } };
};
std::vector<OddsValue> m_initialConsonants;
std::vector<OddsValue> m_medialConsonants;
std::vector<OddsValue> m_finalConsonants;
std::vector<OddsValue> m_vowels;
std::vector<OddsValue> m_specialSyllables;
std::vector<OddsValue> m_professionPatterns;
std::map<char, std::vector<OddsValue> * > m_professions;
std::string selectInitialConsonant(std::string * extra = 0) const;
std::string selectMedialConsonant(std::string * extra = 0) const;
std::string selectFinalConsonant(std::string * extra = 0) const;
std::string selectVowel(std::string * extra = 0) const;
std::string selectSpecialSyllable(std::string * extra = 0) const;
std::string selectProfessionPattern(std::string * extra = 0) const;
std::string selectProfession(char type, std::string * extra = 0) const;
std::string generateSingleName(const NameTemplate &nt) const;
std::string generateProfessionName(const NameTemplate &nt) const;
std::string generateRandomName(const NameTemplate &nt) const;
std::string capitalizeName(const std::string &name) const;
int findRow(DataTable * table, const std::string &column, const std::string &value);
void pushNameTemplate(DataTable * table, int row, const std::string &prefix);
void balanceOdds(std::vector<OddsValue>::iterator begin, std::vector<OddsValue>::iterator end);
std::string selectRandomFrom(std::vector<OddsValue>::const_iterator begin, std::vector<OddsValue>::const_iterator end, std::string * extra = 0) const;
void loadColumn(std::vector<OddsValue> &result, DataTable * source, const std::string &i_language);
void loadColumn(std::vector<OddsValue> &result, DataTable * source, const std::string &i_language, const std::string &filterColumn, const char maskChar);
std::string appendSyllable(const std::string &left, const std::string &right) const;
enum eFragmentType
{
kVowel,
kConsonant,
kSpecial,
kMixed
};
eFragmentType getFragmentType(const std::string &test) const;
bool hasString(const std::vector<OddsValue> &array, const std::string &test) const;
// disable copying
NameGenerator(const NameGenerator &o);
NameGenerator &operator = (const NameGenerator &o);
};
//--------------------------------------------------------------------
inline std::string NameGenerator::selectInitialConsonant(std::string * extra) const
{
return selectRandomFrom(m_initialConsonants.begin(), m_initialConsonants.end(), extra);
}
//--------------------------------------------------------------------
inline std::string NameGenerator::selectMedialConsonant(std::string * extra) const
{
return selectRandomFrom(m_medialConsonants.begin(), m_medialConsonants.end(), extra);
}
//--------------------------------------------------------------------
inline std::string NameGenerator::selectFinalConsonant(std::string * extra) const
{
return selectRandomFrom(m_finalConsonants.begin(), m_finalConsonants.end(), extra);
}
//--------------------------------------------------------------------
inline std::string NameGenerator::selectVowel(std::string * extra) const
{
return selectRandomFrom(m_vowels.begin(), m_vowels.end(), extra);
}
//--------------------------------------------------------------------
inline std::string NameGenerator::selectSpecialSyllable(std::string * extra) const
{
return selectRandomFrom(m_specialSyllables.begin(), m_specialSyllables.end(), extra);
}
//--------------------------------------------------------------------
inline std::string NameGenerator::selectProfessionPattern(std::string * extra) const
{
return selectRandomFrom(m_professionPatterns.begin(), m_professionPatterns.end(), extra);
}
//--------------------------------------------------------------------
inline std::string NameGenerator::selectProfession(char type, std::string * extra) const
{
std::map<char, std::vector<OddsValue> *>::const_iterator i = m_professions.find(type);
if (i==m_professions.end())
return std::string();
return selectRandomFrom(i->second->begin(), i->second->end(), extra);
}
//--------------------------------------------------------------------
inline bool NameGenerator::getInitialized() const
{
return m_initialized;
}
//====================================================================
#endif
@@ -0,0 +1,82 @@
// ======================================================================
//
// NetworkIdAutoDeltaPackedMap.cpp
// copyright (c) 2004 Sony Online Entertainment
//
// ======================================================================
#include "sharedUtility/FirstSharedUtility.h"
#include "sharedUtility/NetworkIdAutoDeltaPackedMap.h"
#include "sharedFoundation/NetworkIdArchive.h"
// ======================================================================
namespace Archive
{
void AutoDeltaPackedMap<int, NetworkId>::pack(ByteStream & target, const std::string & buffer)
{
char temp[200];
char value[200];
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,"%i %s",&c.key, value);
c.value=NetworkId(std::string(value)); // because there's no constructor that takes a char*
Archive::put(target, static_cast<unsigned char>(Command::ADD));
Archive::put(target, c.key);
Archive::put(target, c.value);
tempPos=0;
}
else
{
temp[tempPos++]=*i;
}
}
}
// ======================================================================
void AutoDeltaPackedMap<int, NetworkId>::unpack(ReadIterator & source, std::string & buffer)
{
char temp[200];
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);
snprintf(temp, sizeof(temp)-1, "%i %s:", c.key, c.value.getValueString().c_str());
temp[sizeof(temp)-1]='\0';
buffer+=temp;
}
}
}
}
// ======================================================================

Some files were not shown because too many files have changed in this diff Show More