/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef __DATASTORE_H
#define __DATASTORE_H
#include "Common.h"
#include "Singleton.h"
#include "DBC.h"
template
class SERVER_DECL DataStore : public Singleton >
{
protected:
DBC d;
public:
DataStore(const char* filename)
{
d.Load(filename);
if((sizeof(T) / 4) != d.GetCols())
printf("[DBC] Warning: Incompatible structures. (%s, %u / %u)\n", filename, sizeof(T) / 4, d.GetCols());
}
virtual ~DataStore() {}
virtual T *LookupEntry(const uint32 row)
{
if(!d.IsLoaded() || (uint32)d.GetRows() < row) return NULL;
return (T*)d.GetRow(row);
}
const char* LookupString(const uint32 offset)
{
if(!d.IsLoaded() || (uint32)d.GetDBSize() < offset) return NULL;
return d.LookupString(offset);
}
virtual T* LookupEntryForced(const uint32 row)
{
return DataStore::LookupEntry(row);
}
uint32 GetNumRows()
{
return d.GetRows();
}
};
template
class SERVER_DECL FastIndexedDataStore : public DataStore
{
T ** dataIndex;
uint32 high;
uint32 first;
public:
FastIndexedDataStore(const char * filename) : DataStore(filename)
{
std::map itemp;
high = 0;
first = 0;
T * data;
uint32 index;
for(uint32 row=0;row<(uint32)DataStore::d.GetRows();row++)
{
data = (T*)DataStore::d.GetRow(row);
index = *(int*)data;
if(!first)
first = index;
itemp[index] = (void*)data;
if(index > high)
high = index;
}
++high;
// dump to index array
dataIndex = new T*[high];
memset(dataIndex, 0, sizeof(uint32) * high);
std::map::iterator itr = itemp.begin();
for(; itr != itemp.end(); ++itr)
dataIndex[itr->first] = (T*)itr->second;
}
~FastIndexedDataStore()
{
delete [] dataIndex;
}
T * LookupEntry(const uint32 row)
{
if(row >= high || dataIndex[row] == 0) return dataIndex[first];
return dataIndex[row];
}
T * LookupEntryForced(const uint32 row)
{
if(row >= high) return 0;
return dataIndex[row];
}
T *LookupRow(const uint32 row)
{
return (T*)DataStore::d.GetRow(row);
}
void SetRow(uint32 row, T* data)
{
ASSERT(dataIndex[row]==0 && row
class SERVER_DECL IndexedDataStore : public DataStore
{
protected:
std::map indexMap;
public:
IndexedDataStore(const char* filename) : DataStore(filename)
{
for(uint32 row=0;row<(uint32)DataStore::d.GetRows();row++)
indexMap[*(int*)DataStore::d.GetRow(row)] = row;
}
~IndexedDataStore() { indexMap.clear(); }
virtual T *LookupEntry(const uint32 row)
{
if(!DataStore::d.IsLoaded()) return NULL;
return (T*)DataStore::d.GetRow(indexMap[row]);
}
virtual T *LookupRow(const uint32 row)
{
if(!DataStore::d.IsLoaded()) return NULL;
return (T*)DataStore::d.GetRow(row);
}
};
#define defineDBCStore(name,structname) \
class SERVER_DECL name : public DataStore \
{ \
public: \
name(const char* filename); \
~name(); \
}
#define implementDBCStore(name,structname) \
initialiseSingleton(name); \
initialiseSingleton(DataStore< structname >); \
name::name(const char* filename) : DataStore(filename) {} \
name::~name() {} \
#define defineIndexedDBCStore(name,structname) \
class SERVER_DECL name : public FastIndexedDataStore \
{ \
public: \
name(const char* filename); \
~name(); \
}
#define implementIndexedDBCStore(name,structname) \
initialiseSingleton(name); \
initialiseSingleton(DataStore< structname >); \
name::name(const char* filename) : FastIndexedDataStore(filename) {} \
name::~name() {}
#endif