Core/DataStores: Added iterator class for DBCStorage and DB2Storage

This commit is contained in:
Shauren
2015-02-22 12:44:24 +01:00
parent 8214a14ef8
commit 40b6736f69
7 changed files with 135 additions and 114 deletions

View File

@@ -157,106 +157,83 @@ void DB2Manager::LoadStores(std::string const& dataPath)
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sTaxiPathNodeStore, db2Path, "TaxiPathNode.db2");
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sTaxiPathStore, db2Path, "TaxiPath.db2");
for (uint32 i = 0; i < sItemBonusStore.GetNumRows(); ++i)
if (ItemBonusEntry const* bonus = sItemBonusStore.LookupEntry(i))
_itemBonusLists[bonus->BonusListID].push_back(bonus);
for (ItemBonusEntry const* bonus : sItemBonusStore)
_itemBonusLists[bonus->BonusListID].push_back(bonus);
for (uint32 i = 0; i < sItemBonusTreeNodeStore.GetNumRows(); ++i)
for (ItemBonusTreeNodeEntry const* bonusTreeNode : sItemBonusTreeNodeStore)
{
if (ItemBonusTreeNodeEntry const* bonusTreeNode = sItemBonusTreeNodeStore.LookupEntry(i))
uint32 bonusTreeId = bonusTreeNode->BonusTreeID;
while (bonusTreeNode)
{
uint32 bonusTreeId = bonusTreeNode->BonusTreeID;
while (bonusTreeNode)
{
_itemBonusTrees[bonusTreeId].insert(bonusTreeNode);
bonusTreeNode = sItemBonusTreeNodeStore.LookupEntry(bonusTreeNode->SubTreeID);
}
_itemBonusTrees[bonusTreeId].insert(bonusTreeNode);
bonusTreeNode = sItemBonusTreeNodeStore.LookupEntry(bonusTreeNode->SubTreeID);
}
}
for (uint32 i = 0; i < sItemModifiedAppearanceStore.GetNumRows(); ++i)
if (ItemModifiedAppearanceEntry const* appearanceMod = sItemModifiedAppearanceStore.LookupEntry(i))
if (ItemAppearanceEntry const* appearance = sItemAppearanceStore.LookupEntry(appearanceMod->AppearanceID))
_itemDisplayIDs[appearanceMod->ItemID | (appearanceMod->AppearanceModID << 24)] = appearance->DisplayID;
for (ItemModifiedAppearanceEntry const* appearanceMod : sItemModifiedAppearanceStore)
if (ItemAppearanceEntry const* appearance = sItemAppearanceStore.LookupEntry(appearanceMod->AppearanceID))
_itemDisplayIDs[appearanceMod->ItemID | (appearanceMod->AppearanceModID << 24)] = appearance->DisplayID;
for (uint32 i = 0; i < sItemXBonusTreeStore.GetNumRows(); ++i)
if (ItemXBonusTreeEntry const* itemBonusTreeAssignment = sItemXBonusTreeStore.LookupEntry(i))
_itemToBonusTree.insert({ itemBonusTreeAssignment->ItemID, itemBonusTreeAssignment->BonusTreeID });
for (ItemXBonusTreeEntry const* itemBonusTreeAssignment : sItemXBonusTreeStore)
_itemToBonusTree.insert({ itemBonusTreeAssignment->ItemID, itemBonusTreeAssignment->BonusTreeID });
{
std::set<uint32> scalingCurves;
for (uint32 i = 0; i < sScalingStatDistributionStore.GetNumRows(); ++i)
if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(i))
scalingCurves.insert(ssd->ItemLevelCurveID);
for (ScalingStatDistributionEntry const* ssd : sScalingStatDistributionStore)
scalingCurves.insert(ssd->ItemLevelCurveID);
for (uint32 i = 0; i < sCurvePointStore.GetNumRows(); ++i)
if (CurvePointEntry const* curvePoint = sCurvePointStore.LookupEntry(i))
if (scalingCurves.count(curvePoint->CurveID))
_heirloomCurvePoints[curvePoint->CurveID][curvePoint->Index] = curvePoint;
for (CurvePointEntry const* curvePoint : sCurvePointStore)
if (scalingCurves.count(curvePoint->CurveID))
_heirloomCurvePoints[curvePoint->CurveID][curvePoint->Index] = curvePoint;
}
for (uint32 i = 0; i < sMountStore.GetNumRows(); ++i)
if (MountEntry const* mount = sMountStore.LookupEntry(i))
_mountsBySpellId[mount->SpellId] = mount;
for (MountEntry const* mount : sMountStore)
_mountsBySpellId[mount->SpellId] = mount;
for (uint32 i = 0; i < sPhaseGroupStore.GetNumRows(); ++i)
if (PhaseGroupEntry const* group = sPhaseGroupStore.LookupEntry(i))
if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID))
_phasesByGroup[group->PhaseGroupID].insert(phase->ID);
for (PhaseGroupEntry const* group : sPhaseGroupStore)
if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID))
_phasesByGroup[group->PhaseGroupID].insert(phase->ID);
for (uint32 i = 0; i < sSpellPowerStore.GetNumRows(); ++i)
if (SpellPowerEntry const* power = sSpellPowerStore.LookupEntry(i))
sSpellPowerBySpellIDStore[power->SpellID] = power;
for (SpellPowerEntry const* power : sSpellPowerStore)
sSpellPowerBySpellIDStore[power->SpellID] = power;
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
sTaxiPathSetBySource[entry->From][entry->To] = TaxiPathBySourceAndDestination(entry->ID, entry->Cost);
for (TaxiPathEntry const* entry : sTaxiPathStore)
sTaxiPathSetBySource[entry->From][entry->To] = TaxiPathBySourceAndDestination(entry->ID, entry->Cost);
uint32 pathCount = sTaxiPathStore.GetNumRows();
// Calculate path nodes count
std::vector<uint32> pathLength;
pathLength.resize(pathCount); // 0 and some other indexes not used
for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
{
if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
{
if (pathLength[entry->PathID] < entry->NodeIndex + 1)
pathLength[entry->PathID] = entry->NodeIndex + 1;
}
}
for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore)
if (pathLength[entry->PathID] < entry->NodeIndex + 1)
pathLength[entry->PathID] = entry->NodeIndex + 1;
// Set path length
sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used
for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i)
for (uint32 i = 0; i < sTaxiPathNodesByPath.size(); ++i)
sTaxiPathNodesByPath[i].resize(pathLength[i]);
// fill data
for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
sTaxiPathNodesByPath[entry->PathID].set(entry->NodeIndex, entry);
for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore)
sTaxiPathNodesByPath[entry->PathID].set(entry->NodeIndex, entry);
// Initialize global taxinodes mask
// include existed nodes that have at least single not spell base (scripted) path
{
std::set<uint32> spellPaths;
for (uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i)
if (SpellEffectEntry const* sInfo = sSpellEffectStore.LookupEntry (i))
if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI)
spellPaths.insert(sInfo->EffectMiscValue);
for (SpellEffectEntry const* sInfo : sSpellEffectStore)
if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI)
spellPaths.insert(sInfo->EffectMiscValue);
memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask));
memset(sOldContinentsNodesMask, 0, sizeof(sOldContinentsNodesMask));
memset(sHordeTaxiNodesMask, 0, sizeof(sHordeTaxiNodesMask));
memset(sAllianceTaxiNodesMask, 0, sizeof(sAllianceTaxiNodesMask));
memset(sDeathKnightTaxiNodesMask, 0, sizeof(sDeathKnightTaxiNodesMask));
for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
for (TaxiNodesEntry const* node : sTaxiNodesStore)
{
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
if (!node)
continue;
TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i);
TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(node->ID);
if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty())
{
bool ok = false;
@@ -275,8 +252,8 @@ void DB2Manager::LoadStores(std::string const& dataPath)
}
// valid taxi network node
uint8 field = (uint8)((i - 1) / 8);
uint32 submask = 1 << ((i-1) % 8);
uint8 field = (uint8)((node->ID - 1) / 8);
uint32 submask = 1 << ((node->ID - 1) % 8);
sTaxiNodesMask[field] |= submask;
if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981)
@@ -287,11 +264,11 @@ void DB2Manager::LoadStores(std::string const& dataPath)
sDeathKnightTaxiNodesMask[field] |= submask;
// old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info)
if (node->MapID < 2 || i == 82 || i == 83 || i == 93 || i == 94)
if (node->MapID < 2 || node->ID == 82 || node->ID == 83 || node->ID == 93 || node->ID == 94)
sOldContinentsNodesMask[field] |= submask;
// fix DK node at Ebon Hold and Shadow Vault flight master
if (i == 315 || i == 333)
if (node->ID == 315 || node->ID == 333)
((TaxiNodesEntry*)node)->MountCreatureID[1] = 32981;
}
}

View File

@@ -2404,14 +2404,13 @@ void ObjectMgr::LoadItemTemplates()
uint32 oldMSTime = getMSTime();
uint32 sparseCount = 0;
for (uint32 itemId = 0; itemId < sItemSparseStore.GetNumRows(); ++itemId)
for (ItemSparseEntry const* sparse : sItemSparseStore)
{
ItemSparseEntry const* sparse = sItemSparseStore.LookupEntry(itemId);
ItemEntry const* db2Data = sItemStore.LookupEntry(itemId);
if (!sparse || !db2Data)
ItemEntry const* db2Data = sItemStore.LookupEntry(sparse->ID);
if (!db2Data)
continue;
ItemTemplate& itemTemplate = _itemTemplateStore[itemId];
ItemTemplate& itemTemplate = _itemTemplateStore[sparse->ID];
itemTemplate.BasicData = db2Data;
itemTemplate.ExtendedData = sparse;
@@ -2428,12 +2427,8 @@ void ObjectMgr::LoadItemTemplates()
}
// Load item effects (spells)
for (uint32 effectId = 0; effectId < sItemEffectStore.GetNumRows(); ++effectId)
for (ItemEffectEntry const* effectEntry : sItemEffectStore)
{
ItemEffectEntry const* effectEntry = sItemEffectStore.LookupEntry(effectId);
if (!effectEntry)
continue;
auto itemItr = _itemTemplateStore.find(effectEntry->ItemID);
if (itemItr == _itemTemplateStore.end())
continue;
@@ -5467,34 +5462,32 @@ uint32 ObjectMgr::GetNearestTaxiNode(float x, float y, float z, uint32 mapid, ui
float dist = 10000;
uint32 id = 0;
for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
for (TaxiNodesEntry const* node : sTaxiNodesStore)
{
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
if (!node || node->MapID != mapid || (!node->MountCreatureID[team == ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
continue;
uint8 field = (uint8)((i - 1) / 8);
uint32 submask = 1 << ((i-1) % 8);
uint8 field = (uint8)((node->ID - 1) / 8);
uint32 submask = 1 << ((node->ID - 1) % 8);
// skip not taxi network nodes
if ((sTaxiNodesMask[field] & submask) == 0)
continue;
float dist2 = (node->Pos.X - x)*(node->Pos.X - x)+(node->Pos.Y - y)*(node->Pos.Y - y)+(node->Pos.Z - z)*(node->Pos.Z - z);
float dist2 = (node->Pos.X - x)*(node->Pos.X - x) + (node->Pos.Y - y)*(node->Pos.Y - y) + (node->Pos.Z - z)*(node->Pos.Z - z);
if (found)
{
if (dist2 < dist)
{
dist = dist2;
id = i;
id = node->ID;
}
}
else
{
found = true;
dist = dist2;
id = i;
id = node->ID;
}
}

View File

@@ -1566,12 +1566,8 @@ void SpellMgr::LoadSpellLearnSpells()
}
}
for (uint32 i = 0; i < sSpellLearnSpellStore.GetNumRows(); ++i)
for (SpellLearnSpellEntry const* spellLearnSpell : sSpellLearnSpellStore)
{
SpellLearnSpellEntry const* spellLearnSpell = sSpellLearnSpellStore.LookupEntry(i);
if (!spellLearnSpell)
continue;
if (!GetSpellInfo(spellLearnSpell->SpellID))
continue;

View File

@@ -949,35 +949,31 @@ public:
int32 locale = handler->GetSessionDbcLocale();
// Search in TaxiNodes.dbc
for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
for (TaxiNodesEntry const* nodeEntry : sTaxiNodesStore)
{
TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(id);
if (nodeEntry)
std::string name = nodeEntry->Name_lang->Str[locale];
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
continue;
if (maxResults && count++ == maxResults)
{
std::string name = nodeEntry->Name_lang->Str[locale];
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
continue;
if (maxResults && count++ == maxResults)
{
handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
return true;
}
// send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
if (handler->GetSession())
handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), "",
nodeEntry->MapID, nodeEntry->Pos.X, nodeEntry->Pos.Y, nodeEntry->Pos.Z);
else
handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), "",
nodeEntry->MapID, nodeEntry->Pos.X, nodeEntry->Pos.Y, nodeEntry->Pos.Z);
if (!found)
found = true;
handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
return true;
}
// send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
if (handler->GetSession())
handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, nodeEntry->ID, nodeEntry->ID, name.c_str(), "",
nodeEntry->MapID, nodeEntry->Pos.X, nodeEntry->Pos.Y, nodeEntry->Pos.Z);
else
handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, nodeEntry->ID, name.c_str(), "",
nodeEntry->MapID, nodeEntry->Pos.X, nodeEntry->Pos.Y, nodeEntry->Pos.Z);
if (!found)
found = true;
}
if (!found)
handler->SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);

View File

@@ -20,6 +20,7 @@
#include "Common.h"
#include "DB2StorageLoader.h"
#include "DBStorageIterator.h"
#include "ByteBuffer.h"
/// Interface class for common access
@@ -45,6 +46,8 @@ class DB2Storage : public DB2StorageBase
{
typedef std::list<char*> StringPoolList;
public:
typedef DBStorageIterator<T> iterator;
DB2Storage(char const* f, int32 preparedStmtIndex = -1)
: _indexTableSize(0), _fieldCount(0), _format(f), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
{
@@ -197,6 +200,9 @@ public:
_indexTableSize = 0;
}
iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); }
iterator end() { return iterator(_indexTable.AsT, _indexTableSize, _indexTableSize); }
private:
uint32 _indexTableSize;
uint32 _fieldCount;

View File

@@ -20,6 +20,7 @@
#define DBCSTORE_H
#include "DBCFileLoader.h"
#include "DBStorageIterator.h"
#include "Log.h"
#include "Field.h"
#include "DatabaseWorkerPool.h"
@@ -72,8 +73,11 @@ private:
template<class T>
class DBCStorage
{
typedef std::list<char*> StringPoolList;
typedef std::list<char*> StringPoolList;
public:
typedef DBStorageIterator<T> iterator;
explicit DBCStorage(char const* f)
: fmt(f), nCount(0), fieldCount(0), dataTable(NULL)
{
@@ -296,6 +300,9 @@ class DBCStorage
nCount = 0;
}
iterator begin() { return iterator(indexTable.asT, nCount); }
iterator end() { return iterator(indexTable.asT, nCount, nCount); }
private:
char const* fmt;
uint32 nCount;

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
*
* 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 2 of the License, or (at your
* option) 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 <http://www.gnu.org/licenses/>.
*/
#ifndef DBStorageIterator_h__
#define DBStorageIterator_h__
#include "Define.h"
#include <iterator>
template<class T>
class DBStorageIterator : public std::iterator<std::forward_iterator_tag, T>
{
public:
DBStorageIterator() : _index(nullptr), _pos(0), _end(0) { }
DBStorageIterator(T** index, uint32 size, uint32 pos = 0) : _index(index), _pos(pos), _end(size) { while (_pos < _end && !_index[++_pos]); }
T* operator->() { return _index[_pos]; }
T* operator*() { return _index[_pos]; }
bool operator==(DBStorageIterator const& right) const { /*ASSERT(_index == right._index, "Iterator belongs to a different container")*/ return _pos == right._pos; }
bool operator!=(DBStorageIterator const& right) const { return !(*this == right); }
DBStorageIterator& operator++() { while (_pos < _end && !_index[++_pos]); return *this; }
DBStorageIterator operator++(int) { DBStorageIterator tmp = *this; ++*this; return tmp; }
private:
T** _index;
uint32 _pos;
uint32 _end;
};
#endif // DBStorageIterator_h__