1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-03 02:19:41 +00:00

Fixed unbearably slow cell loader. Faster now.

This commit is contained in:
Nicolay Korslund 2010-05-23 14:40:38 +02:00
parent 8feb987a60
commit 2d2804b30c
8 changed files with 71 additions and 50 deletions

View file

@ -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)

View file

@ -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();

View file

@ -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;
int rec = store.find(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)
/* 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;
) cout << " (NOT FOUND)";
cout << endl;
case 0: cout << "Cell reference " + ref.refID + " not found!\n"; break;
default:
assert(0);
}
}
cout << "Statics in cell: " << statics.list.size() << endl;
}

View file

@ -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;
}
};

View file

@ -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
{

View file

@ -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";

View file

@ -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;

View file

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