Fixed unbearably slow cell loader. Faster now.

actorid
Nicolay Korslund 15 years ago
parent 8feb987a60
commit 2d2804b30c

@ -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;
) cout << " (NOT FOUND)"; case REC_PROB: probes.find(ref, store.probes); break;
case REC_REPA: repairs.find(ref, store.repairs); break;
cout << endl; case REC_STAT: statics.find(ref, store.statics); break;
case REC_WEAP: weapons.find(ref, store.weapons); break;
case 0: cout << "Cell reference " + ref.refID + " not found!\n"; break;
default:
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…
Cancel
Save