mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 20:53:50 +00:00
Fixed unbearably slow cell loader. Faster now.
This commit is contained in:
parent
8feb987a60
commit
2d2804b30c
8 changed files with 71 additions and 50 deletions
|
@ -11,7 +11,7 @@ set(BSA bsa/bsa_archive.cpp bsa/bsa_file.cpp)
|
||||||
set(NIF nif/nif_file.cpp nifogre/ogre_nif_loader.cpp)
|
set(NIF nif/nif_file.cpp nifogre/ogre_nif_loader.cpp)
|
||||||
set(TOOLS tools/stringops.cpp)
|
set(TOOLS tools/stringops.cpp)
|
||||||
set(MANGLE_VFS mangle/vfs/servers/ogre_vfs.cpp)
|
set(MANGLE_VFS mangle/vfs/servers/ogre_vfs.cpp)
|
||||||
set(GAME game/main.cpp game/esm_store.cpp game/cell_store.cpp game/setup.cpp)
|
set(GAME game/main.cpp game/esm_store/store.cpp game/cell_store.cpp game/setup.cpp)
|
||||||
|
|
||||||
# Platform specific
|
# Platform specific
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
|
@ -118,9 +118,6 @@ struct Cell
|
||||||
|
|
||||||
void load(ESMReader &esm)
|
void load(ESMReader &esm)
|
||||||
{
|
{
|
||||||
// All cells have a name record, even nameless exterior cells.
|
|
||||||
name = esm.getHNString("NAME");
|
|
||||||
|
|
||||||
// Ignore this for now, it might mean we should delete the entire
|
// Ignore this for now, it might mean we should delete the entire
|
||||||
// cell?
|
// cell?
|
||||||
if(esm.isNextSub("DELE")) esm.skipHSub();
|
if(esm.isNextSub("DELE")) esm.skipHSub();
|
||||||
|
|
|
@ -31,33 +31,41 @@ void CellStore::loadRefs(const Cell &cell, const ESMStore &store, ESMReader &esm
|
||||||
// Get each reference in turn
|
// Get each reference in turn
|
||||||
while(cell.getNextRef(esm, ref))
|
while(cell.getNextRef(esm, ref))
|
||||||
{
|
{
|
||||||
cout << "Reference: " << ref.refID;
|
int rec = store.find(ref.refID);
|
||||||
|
|
||||||
// Check each list in turn. Potential for optimization.
|
/* We can optimize this further by storing the pointer to the
|
||||||
if(
|
record itself in store.all, so that we don't need to look it
|
||||||
activators .find(ref, store.activators) &&
|
up again here. However, never optimize. There are infinite
|
||||||
potions .find(ref, store.potions) &&
|
opportunities to do that later.
|
||||||
appas .find(ref, store.appas) &&
|
*/
|
||||||
armors .find(ref, store.armors) &&
|
switch(rec)
|
||||||
books .find(ref, store.books) &&
|
{
|
||||||
clothes .find(ref, store.clothes) &&
|
case REC_ACTI: activators.find(ref, store.activators); break;
|
||||||
containers .find(ref, store.containers) &&
|
case REC_ALCH: potions.find(ref, store.potions); break;
|
||||||
creatures .find(ref, store.creatures) &&
|
case REC_APPA: appas.find(ref, store.appas); break;
|
||||||
doors .find(ref, store.doors) &&
|
case REC_ARMO: armors.find(ref, store.armors); break;
|
||||||
ingreds .find(ref, store.ingreds) &&
|
case REC_BOOK: books.find(ref, store.books); break;
|
||||||
creatureLists .find(ref, store.creatureLists) &&
|
case REC_CLOT: clothes.find(ref, store.clothes); break;
|
||||||
itemLists .find(ref, store.itemLists) &&
|
case REC_CONT: containers.find(ref, store.containers); break;
|
||||||
lights .find(ref, store.lights) &&
|
case REC_CREA: creatures.find(ref, store.creatures); break;
|
||||||
lockpicks .find(ref, store.lockpicks) &&
|
case REC_DOOR: doors.find(ref, store.doors); break;
|
||||||
miscItems .find(ref, store.miscItems) &&
|
case REC_INGR: ingreds.find(ref, store.ingreds); break;
|
||||||
npcs .find(ref, store.npcs) &&
|
case REC_LEVC: creatureLists.find(ref, store.creatureLists); break;
|
||||||
probes .find(ref, store.probes) &&
|
case REC_LEVI: itemLists.find(ref, store.itemLists); break;
|
||||||
repairs .find(ref, store.repairs) &&
|
case REC_LIGH: lights.find(ref, store.lights); break;
|
||||||
statics .find(ref, store.statics) &&
|
case REC_LOCK: lockpicks.find(ref, store.lockpicks); break;
|
||||||
weapons .find(ref, store.weapons)
|
case REC_MISC: miscItems.find(ref, store.miscItems); break;
|
||||||
|
case REC_NPC_: npcs.find(ref, store.npcs); break;
|
||||||
|
case REC_PROB: probes.find(ref, store.probes); break;
|
||||||
|
case REC_REPA: repairs.find(ref, store.repairs); break;
|
||||||
|
case REC_STAT: statics.find(ref, store.statics); break;
|
||||||
|
case REC_WEAP: weapons.find(ref, store.weapons); break;
|
||||||
|
|
||||||
) cout << " (NOT FOUND)";
|
case 0: cout << "Cell reference " + ref.refID + " not found!\n"; break;
|
||||||
|
default:
|
||||||
cout << endl;
|
assert(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Statics in cell: " << statics.list.size() << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
(looking up references.) Neither of these modules depend on us.
|
(looking up references.) Neither of these modules depend on us.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "esm_store.hpp"
|
#include "esm_store/store.hpp"
|
||||||
#include "esm/records.hpp"
|
#include "esm/records.hpp"
|
||||||
|
#include "mangle/tools/str_exception.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace ESMS
|
namespace ESMS
|
||||||
|
@ -45,12 +46,13 @@ namespace ESMS
|
||||||
|
|
||||||
// Search for the given reference in the given reclist from
|
// Search for the given reference in the given reclist from
|
||||||
// ESMStore. Insert the reference into the list if a match is
|
// ESMStore. Insert the reference into the list if a match is
|
||||||
// found, and returns false. Returns true if no match is found.
|
// found. If not, throw an exception.
|
||||||
template <typename Y>
|
template <typename Y>
|
||||||
bool find(CellRef &ref, Y recList)
|
void find(CellRef &ref, Y recList)
|
||||||
{
|
{
|
||||||
const X* obj = recList.find(ref.refID);
|
const X* obj = recList.find(ref.refID);
|
||||||
if(obj == NULL) return true;
|
if(obj == NULL)
|
||||||
|
throw str_exception("Error resolving cell reference " + ref.refID);
|
||||||
|
|
||||||
LiveRef lr;
|
LiveRef lr;
|
||||||
lr.ref = ref;
|
lr.ref = ref;
|
||||||
|
@ -58,8 +60,6 @@ namespace ESMS
|
||||||
lr.custom = NULL;
|
lr.custom = NULL;
|
||||||
|
|
||||||
list.push_back(lr);
|
list.push_back(lr);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace ESMS
|
||||||
|
|
||||||
struct RecList
|
struct RecList
|
||||||
{
|
{
|
||||||
virtual void load(ESMReader &esm) = 0;
|
virtual void load(ESMReader &esm, const std::string &id) = 0;
|
||||||
virtual int getSize() = 0;
|
virtual int getSize() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,10 +26,8 @@ namespace ESMS
|
||||||
MapType list;
|
MapType list;
|
||||||
|
|
||||||
// Load one object of this type
|
// Load one object of this type
|
||||||
void load(ESMReader &esm)
|
void load(ESMReader &esm, const std::string &id)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
|
|
||||||
X &ref = list[id];
|
X &ref = list[id];
|
||||||
ref.load(esm);
|
ref.load(esm);
|
||||||
}
|
}
|
||||||
|
@ -55,10 +53,8 @@ namespace ESMS
|
||||||
|
|
||||||
MapType list;
|
MapType list;
|
||||||
|
|
||||||
void load(ESMReader &esm)
|
void load(ESMReader &esm, const std::string &id)
|
||||||
{
|
{
|
||||||
std::string id = esm.getHNString("NAME");
|
|
||||||
|
|
||||||
X &ref = list[id];
|
X &ref = list[id];
|
||||||
ref.id = id;
|
ref.id = id;
|
||||||
ref.load(esm);
|
ref.load(esm);
|
||||||
|
@ -94,20 +90,23 @@ namespace ESMS
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(ESMReader &esm)
|
void load(ESMReader &esm, const std::string &id)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
// The cell itself takes care of all the hairy details
|
// All cells have a name record, even nameless exterior cells.
|
||||||
Cell cell;
|
Cell cell;
|
||||||
|
cell.name = id;
|
||||||
|
|
||||||
|
// The cell itself takes care of all the hairy details
|
||||||
cell.load(esm);
|
cell.load(esm);
|
||||||
|
|
||||||
if(cell.data.flags & Cell::Interior)
|
if(cell.data.flags & Cell::Interior)
|
||||||
{
|
{
|
||||||
// Store interior cell by name
|
// Store interior cell by name
|
||||||
intCells[cell.name] = cell;
|
intCells[id] = cell;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
|
@ -1,6 +1,6 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "esm_store.hpp"
|
#include "store.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ESM;
|
using namespace ESM;
|
||||||
|
@ -36,7 +36,12 @@ void ESMStore::load(ESMReader &esm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load it
|
// Load it
|
||||||
it->second->load(esm);
|
std::string id = esm.getHNOString("NAME");
|
||||||
|
it->second->load(esm, id);
|
||||||
|
|
||||||
|
// Insert the reference into the global lookup
|
||||||
|
if(!id.empty())
|
||||||
|
all[id] = n.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "\n" << recLists.size() << " record types:\n";
|
cout << "\n" << recLists.size() << " record types:\n";
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "esm/records.hpp"
|
#include "esm/records.hpp"
|
||||||
#include "esm_reclists.hpp"
|
#include "reclists.hpp"
|
||||||
|
|
||||||
namespace ESMS
|
namespace ESMS
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,19 @@ namespace ESMS
|
||||||
//RecListT<Skill> skills;
|
//RecListT<Skill> skills;
|
||||||
//RecListT<PathGrid> pathgrids;
|
//RecListT<PathGrid> pathgrids;
|
||||||
|
|
||||||
|
// Lookup of all IDs. Makes looking up references faster. Just
|
||||||
|
// maps the id name to the record type.
|
||||||
|
typedef std::map<std::string, int> AllMap;
|
||||||
|
AllMap all;
|
||||||
|
|
||||||
|
// Look up the given ID in 'all'. Returns 0 if not found.
|
||||||
|
int find(const std::string &id) const
|
||||||
|
{
|
||||||
|
AllMap::const_iterator it = all.find(id);
|
||||||
|
if(it == all.end()) return 0;
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
ESMStore()
|
ESMStore()
|
||||||
{
|
{
|
||||||
recLists[REC_ACTI] = &activators;
|
recLists[REC_ACTI] = &activators;
|
|
@ -1,6 +1,5 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "esm_store.hpp"
|
|
||||||
#include "cell_store.hpp"
|
#include "cell_store.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
Loading…
Reference in a new issue