mirror of
https://github.com/SWG-Source/src.git
synced 2026-10-08 00:12:55 -04:00
Added sharedGame sharedMathArchive and sharedUtility libraries
This commit is contained in:
@@ -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"
|
||||
+1
@@ -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"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/InstallationResourceData.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/InstallationResourceDataArchive.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/InteriorLayoutReaderWriter.h"
|
||||
+1
@@ -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"
|
||||
+1
@@ -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"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/StartingLocationData.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/StartingLocationDataArchive.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/StartingLocationManager.h"
|
||||
+1
@@ -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"
|
||||
+1
@@ -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"
|
||||
+1
@@ -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
Reference in New Issue
Block a user