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(TOOLS tools/stringops.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
if (WIN32)

@ -118,9 +118,6 @@ struct Cell
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
// cell?
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
while(cell.getNextRef(esm, ref))
{
cout << "Reference: " << ref.refID;
// Check each list in turn. Potential for optimization.
if(
activators .find(ref, store.activators) &&
potions .find(ref, store.potions) &&
appas .find(ref, store.appas) &&
armors .find(ref, store.armors) &&
books .find(ref, store.books) &&
clothes .find(ref, store.clothes) &&
containers .find(ref, store.containers) &&
creatures .find(ref, store.creatures) &&
doors .find(ref, store.doors) &&
ingreds .find(ref, store.ingreds) &&
creatureLists .find(ref, store.creatureLists) &&
itemLists .find(ref, store.itemLists) &&
lights .find(ref, store.lights) &&
lockpicks .find(ref, store.lockpicks) &&
miscItems .find(ref, store.miscItems) &&
npcs .find(ref, store.npcs) &&
probes .find(ref, store.probes) &&
repairs .find(ref, store.repairs) &&
statics .find(ref, store.statics) &&
weapons .find(ref, store.weapons)
) cout << " (NOT FOUND)";
cout << endl;
int rec = store.find(ref.refID);
/* We can optimize this further by storing the pointer to the
record itself in store.all, so that we don't need to look it
up again here. However, never optimize. There are infinite
opportunities to do that later.
*/
switch(rec)
{
case REC_ACTI: activators.find(ref, store.activators); break;
case REC_ALCH: potions.find(ref, store.potions); break;
case REC_APPA: appas.find(ref, store.appas); break;
case REC_ARMO: armors.find(ref, store.armors); break;
case REC_BOOK: books.find(ref, store.books); break;
case REC_CLOT: clothes.find(ref, store.clothes); break;
case REC_CONT: containers.find(ref, store.containers); break;
case REC_CREA: creatures.find(ref, store.creatures); break;
case REC_DOOR: doors.find(ref, store.doors); break;
case REC_INGR: ingreds.find(ref, store.ingreds); break;
case REC_LEVC: creatureLists.find(ref, store.creatureLists); break;
case REC_LEVI: itemLists.find(ref, store.itemLists); break;
case REC_LIGH: lights.find(ref, store.lights); break;
case REC_LOCK: lockpicks.find(ref, store.lockpicks); break;
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;
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.
*/
#include "esm_store.hpp"
#include "esm_store/store.hpp"
#include "esm/records.hpp"
#include "mangle/tools/str_exception.h"
#include <list>
namespace ESMS
@ -45,12 +46,13 @@ namespace ESMS
// Search for the given reference in the given reclist from
// 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>
bool find(CellRef &ref, Y recList)
void find(CellRef &ref, Y recList)
{
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;
lr.ref = ref;
@ -58,8 +60,6 @@ namespace ESMS
lr.custom = NULL;
list.push_back(lr);
return false;
}
};

@ -12,7 +12,7 @@ namespace ESMS
struct RecList
{
virtual void load(ESMReader &esm) = 0;
virtual void load(ESMReader &esm, const std::string &id) = 0;
virtual int getSize() = 0;
};
@ -26,10 +26,8 @@ namespace ESMS
MapType list;
// 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];
ref.load(esm);
}
@ -55,10 +53,8 @@ namespace ESMS
MapType list;
void load(ESMReader &esm)
void load(ESMReader &esm, const std::string &id)
{
std::string id = esm.getHNString("NAME");
X &ref = list[id];
ref.id = id;
ref.load(esm);
@ -94,20 +90,23 @@ namespace ESMS
return &it->second;
}
void load(ESMReader &esm)
void load(ESMReader &esm, const std::string &id)
{
using namespace std;
count++;
// The cell itself takes care of all the hairy details
// All cells have a name record, even nameless exterior cells.
Cell cell;
cell.name = id;
// The cell itself takes care of all the hairy details
cell.load(esm);
if(cell.data.flags & Cell::Interior)
{
// Store interior cell by name
intCells[cell.name] = cell;
intCells[id] = cell;
}
else
{

@ -1,6 +1,6 @@
#include <set>
#include <iostream>
#include "esm_store.hpp"
#include "store.hpp"
using namespace std;
using namespace ESM;
@ -36,7 +36,12 @@ void ESMStore::load(ESMReader &esm)
}
// 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";

@ -15,7 +15,7 @@
*/
#include "esm/records.hpp"
#include "esm_reclists.hpp"
#include "reclists.hpp"
namespace ESMS
{
@ -78,6 +78,19 @@ namespace ESMS
//RecListT<Skill> skills;
//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()
{
recLists[REC_ACTI] = &activators;

@ -1,6 +1,5 @@
#include <iostream>
#include "esm_store.hpp"
#include "cell_store.hpp"
using namespace std;

Loading…
Cancel
Save