1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 09:35:28 +00:00

refactored NIFFile parse to get better code/data seperation

This commit is contained in:
Nathan Jeffords 2013-01-03 23:59:32 -08:00
parent 6de6d9ff6e
commit 0ed2015319

View File

@ -185,6 +185,101 @@ NIFFile::~NIFFile()
delete records[i]; delete records[i];
} }
template <typename NodeType> static Record* construct() { return new NodeType; }
struct RecordFactoryEntry {
typedef Record* (*create_t) ();
char const * mName;
create_t mCreate;
RecordType mType;
};
/* These are all the record types we know how to read.
This can be heavily optimized later if needed. For example, a
hash table or a FSM-based parser could be used to look up
node names.
*/
static const RecordFactoryEntry recordFactories [] = {
{ "NiNode", &construct <NiNode >, RC_NiNode },
{ "AvoidNode", &construct <NiNode >, RC_NiNode },
{ "NiBSParticleNode", &construct <NiNode >, RC_NiNode },
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiNode },
{ "NiBillboardNode", &construct <NiNode >, RC_NiNode },
{ "NiTriShape", &construct <NiTriShape >, RC_NiTriShape },
{ "NiRotatingParticles", &construct <NiRotatingParticles >, RC_NiRotatingParticles },
{ "NiAutoNormalParticles", &construct <NiAutoNormalParticles >, RC_NiAutoNormalParticles },
{ "NiCamera", &construct <NiCamera >, RC_NiCamera },
{ "RootCollisionNode", &construct <NiNode >, RC_RootCollisionNode },
{ "NiTexturingProperty", &construct <NiTexturingProperty >, RC_NiTexturingProperty },
{ "NiMaterialProperty", &construct <NiMaterialProperty >, RC_NiMaterialProperty },
{ "NiZBufferProperty", &construct <NiZBufferProperty >, RC_NiZBufferProperty },
{ "NiAlphaProperty", &construct <NiAlphaProperty >, RC_NiAlphaProperty },
{ "NiVertexColorProperty", &construct <NiVertexColorProperty >, RC_NiVertexColorProperty },
{ "NiShadeProperty", &construct <NiShadeProperty >, RC_NiShadeProperty },
{ "NiDitherProperty", &construct <NiDitherProperty >, RC_NiDitherProperty },
{ "NiWireframeProperty", &construct <NiWireframeProperty >, RC_NiWireframeProperty },
{ "NiSpecularProperty", &construct <NiSpecularProperty >, RC_NiSpecularProperty },
{ "NiStencilProperty", &construct <NiStencilProperty >, RC_NiStencilProperty },
{ "NiVisController", &construct <NiVisController >, RC_NiVisController },
{ "NiGeomMorpherController", &construct <NiGeomMorpherController >, RC_NiGeomMorpherController },
{ "NiKeyframeController", &construct <NiKeyframeController >, RC_NiKeyframeController },
{ "NiAlphaController", &construct <NiAlphaController >, RC_NiAlphaController },
{ "NiUVController", &construct <NiUVController >, RC_NiUVController },
{ "NiPathController", &construct <NiPathController >, RC_NiPathController },
{ "NiMaterialColorController", &construct <NiMaterialColorController >, RC_NiMaterialColorController },
{ "NiBSPArrayController", &construct <NiBSPArrayController >, RC_NiBSPArrayController },
{ "NiParticleSystemController", &construct <NiParticleSystemController >, RC_NiParticleSystemController },
{ "NiAmbientLight", &construct <NiLight >, RC_NiLight },
{ "NiDirectionalLight", &construct <NiLight >, RC_NiLight },
{ "NiTextureEffect", &construct <NiTextureEffect >, RC_NiTextureEffect },
{ "NiVertWeightsExtraData", &construct <NiVertWeightsExtraData >, RC_NiVertWeightsExtraData },
{ "NiTextKeyExtraData", &construct <NiTextKeyExtraData >, RC_NiTextKeyExtraData },
{ "NiStringExtraData", &construct <NiStringExtraData >, RC_NiStringExtraData },
{ "NiGravity", &construct <NiGravity >, RC_NiGravity },
{ "NiPlanarCollider", &construct <NiPlanarCollider >, RC_NiPlanarCollider },
{ "NiParticleGrowFade", &construct <NiParticleGrowFade >, RC_NiParticleGrowFade },
{ "NiParticleColorModifier", &construct <NiParticleColorModifier >, RC_NiParticleColorModifier },
{ "NiParticleRotation", &construct <NiParticleRotation >, RC_NiParticleRotation },
{ "NiFloatData", &construct <NiFloatData >, RC_NiFloatData },
{ "NiTriShapeData", &construct <NiTriShapeData >, RC_NiTriShapeData },
{ "NiVisData", &construct <NiVisData >, RC_NiVisData },
{ "NiColorData", &construct <NiColorData >, RC_NiColorData },
{ "NiPixelData", &construct <NiPixelData >, RC_NiPixelData },
{ "NiMorphData", &construct <NiMorphData >, RC_NiMorphData },
{ "NiKeyframeData", &construct <NiKeyframeData >, RC_NiKeyframeData },
{ "NiSkinData", &construct <NiSkinData >, RC_NiSkinData },
{ "NiUVData", &construct <NiUVData >, RC_NiUVData },
{ "NiPosData", &construct <NiPosData >, RC_NiPosData },
{ "NiRotatingParticlesData", &construct <NiRotatingParticlesData >, RC_NiRotatingParticlesData },
{ "NiAutoNormalParticlesData", &construct <NiAutoNormalParticlesData >, RC_NiAutoNormalParticlesData },
{ "NiSequenceStreamHelper", &construct <NiSequenceStreamHelper >, RC_NiSequenceStreamHelper },
{ "NiSourceTexture", &construct <NiSourceTexture >, RC_NiSourceTexture },
{ "NiSkinInstance", &construct <NiSkinInstance >, RC_NiSkinInstance },
};
static RecordFactoryEntry const * recordFactories_begin = &recordFactories [0];
static RecordFactoryEntry const * recordFactories_end = &recordFactories [sizeof (recordFactories) / sizeof (recordFactories[0])];
RecordFactoryEntry const * lookupRecordFactory (char const * name)
{
RecordFactoryEntry const * i;
for (i = recordFactories_begin; i != recordFactories_end; ++i)
if (strcmp (name, i->mName) == 0)
break;
if (i == recordFactories_end)
return NULL;
return i;
}
/* This file implements functions from the NIFFile class. It is also /* This file implements functions from the NIFFile class. It is also
where we stash all the functions we couldn't add as inline where we stash all the functions we couldn't add as inline
definitions in the record types. definitions in the record types.
@ -223,88 +318,15 @@ void NIFFile::parse()
std::string rec = nif.getString(); std::string rec = nif.getString();
/* These are all the record types we know how to read. RecordFactoryEntry const * entry = lookupRecordFactory (rec.c_str ());
This can be heavily optimized later if needed. For example, a if (entry != NULL)
hash table or a FSM-based parser could be used to look up {
node names. r = entry->mCreate ();
*/ r->recType = entry->mType;
}
// NiNodes
if(rec == "NiNode" || rec == "AvoidNode" ||
rec == "NiBSParticleNode" ||
rec == "NiBSAnimationNode" ||
rec == "NiBillboardNode") { r = new NiNode; r->recType = RC_NiNode; }
// Other nodes
else if(rec == "NiTriShape") { r = new NiTriShape; r->recType = RC_NiTriShape; }
else if(rec == "NiRotatingParticles") { r = new NiRotatingParticles; r->recType = RC_NiRotatingParticles; }
else if(rec == "NiAutoNormalParticles") { r = new NiAutoNormalParticles; r->recType = RC_NiAutoNormalParticles; }
else if(rec == "NiCamera") { r = new NiCamera; r->recType = RC_NiCamera; }
else if(rec == "RootCollisionNode"){ r = new NiNode; r->recType = RC_RootCollisionNode; }// a root collision node is exactly like a node
//that's why there is no need to create a new type
// Properties
else if(rec == "NiTexturingProperty") { r = new NiTexturingProperty; r->recType = RC_NiTexturingProperty; }
else if(rec == "NiMaterialProperty") { r = new NiMaterialProperty; r->recType = RC_NiMaterialProperty; }
else if(rec == "NiZBufferProperty") { r = new NiZBufferProperty; r->recType = RC_NiZBufferProperty; }
else if(rec == "NiAlphaProperty") { r = new NiAlphaProperty; r->recType = RC_NiAlphaProperty; }
else if(rec == "NiVertexColorProperty") { r = new NiVertexColorProperty; r->recType = RC_NiVertexColorProperty; }
else if(rec == "NiShadeProperty") { r = new NiShadeProperty; r->recType = RC_NiShadeProperty; }
else if(rec == "NiDitherProperty") { r = new NiDitherProperty; r->recType = RC_NiDitherProperty; }
else if(rec == "NiWireframeProperty") { r = new NiWireframeProperty; r->recType = RC_NiWireframeProperty; }
else if(rec == "NiSpecularProperty") { r = new NiSpecularProperty; r->recType = RC_NiSpecularProperty; }
else if(rec == "NiStencilProperty") { r = new NiStencilProperty; r->recType = RC_NiStencilProperty; }
// Controllers
else if(rec == "NiVisController") { r = new NiVisController; r->recType = RC_NiVisController; }
else if(rec == "NiGeomMorpherController") { r = new NiGeomMorpherController; r->recType = RC_NiGeomMorpherController; }
else if(rec == "NiKeyframeController") { r = new NiKeyframeController; r->recType = RC_NiKeyframeController; }
else if(rec == "NiAlphaController") { r = new NiAlphaController; r->recType = RC_NiAlphaController; }
else if(rec == "NiUVController") { r = new NiUVController; r->recType = RC_NiUVController; }
else if(rec == "NiPathController") { r = new NiPathController; r->recType = RC_NiPathController; }
else if(rec == "NiMaterialColorController") { r = new NiMaterialColorController; r->recType = RC_NiMaterialColorController; }
else if(rec == "NiBSPArrayController") { r = new NiBSPArrayController; r->recType = RC_NiBSPArrayController; }
else if(rec == "NiParticleSystemController") { r = new NiParticleSystemController; r->recType = RC_NiParticleSystemController; }
// Effects
else if(rec == "NiAmbientLight" ||
rec == "NiDirectionalLight") { r = new NiLight; r->recType = RC_NiLight; }
else if(rec == "NiTextureEffect") { r = new NiTextureEffect; r->recType = RC_NiTextureEffect; }
// Extra Data
else if(rec == "NiVertWeightsExtraData") { r = new NiVertWeightsExtraData; r->recType = RC_NiVertWeightsExtraData; }
else if(rec == "NiTextKeyExtraData") { r = new NiTextKeyExtraData; r->recType = RC_NiTextKeyExtraData; }
else if(rec == "NiStringExtraData") { r = new NiStringExtraData; r->recType = RC_NiStringExtraData; }
else if(rec == "NiGravity") { r = new NiGravity; r->recType = RC_NiGravity; }
else if(rec == "NiPlanarCollider") { r = new NiPlanarCollider; r->recType = RC_NiPlanarCollider; }
else if(rec == "NiParticleGrowFade") { r = new NiParticleGrowFade; r->recType = RC_NiParticleGrowFade; }
else if(rec == "NiParticleColorModifier") { r = new NiParticleColorModifier; r->recType = RC_NiParticleColorModifier; }
else if(rec == "NiParticleRotation") { r = new NiParticleRotation; r->recType = RC_NiParticleRotation; }
// Data
else if(rec == "NiFloatData") { r = new NiFloatData; r->recType = RC_NiFloatData; }
else if(rec == "NiTriShapeData") { r = new NiTriShapeData; r->recType = RC_NiTriShapeData; }
else if(rec == "NiVisData") { r = new NiVisData; r->recType = RC_NiVisData; }
else if(rec == "NiColorData") { r = new NiColorData; r->recType = RC_NiColorData; }
else if(rec == "NiPixelData") { r = new NiPixelData; r->recType = RC_NiPixelData; }
else if(rec == "NiMorphData") { r = new NiMorphData; r->recType = RC_NiMorphData; }
else if(rec == "NiKeyframeData") { r = new NiKeyframeData; r->recType = RC_NiKeyframeData; }
else if(rec == "NiSkinData") { r = new NiSkinData; r->recType = RC_NiSkinData; }
else if(rec == "NiUVData") { r = new NiUVData; r->recType = RC_NiUVData; }
else if(rec == "NiPosData") { r = new NiPosData; r->recType = RC_NiPosData; }
else if(rec == "NiRotatingParticlesData") { r = new NiRotatingParticlesData; r->recType = RC_NiRotatingParticlesData; }
else if(rec == "NiAutoNormalParticlesData") { r = new NiAutoNormalParticlesData; r->recType = RC_NiAutoNormalParticlesData; }
// Other
else if(rec == "NiSequenceStreamHelper") { r = new NiSequenceStreamHelper; r->recType = RC_NiSequenceStreamHelper; }
else if(rec == "NiSourceTexture") { r = new NiSourceTexture; r->recType = RC_NiSourceTexture; }
else if(rec == "NiSkinInstance") { r = new NiSkinInstance; r->recType = RC_NiSkinInstance; }
// Failure
else else
fail("Unknown record type " + rec); fail("Unknown record type " + rec);
assert(r != NULL); assert(r != NULL);
assert(r->recType != RC_MISSING); assert(r->recType != RC_MISSING);