From 0ed2015319a0afa2c59a393e7e876572af419134 Mon Sep 17 00:00:00 2001 From: Nathan Jeffords Date: Thu, 3 Jan 2013 23:59:32 -0800 Subject: [PATCH] refactored NIFFile parse to get better code/data seperation --- components/nif/nif_file.cpp | 184 ++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 81 deletions(-) diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index f3faf563c..dc8670cba 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -185,6 +185,101 @@ NIFFile::~NIFFile() delete records[i]; } +template 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 , RC_NiNode }, + { "AvoidNode", &construct , RC_NiNode }, + { "NiBSParticleNode", &construct , RC_NiNode }, + { "NiBSAnimationNode", &construct , RC_NiNode }, + { "NiBillboardNode", &construct , RC_NiNode }, + { "NiTriShape", &construct , RC_NiTriShape }, + { "NiRotatingParticles", &construct , RC_NiRotatingParticles }, + { "NiAutoNormalParticles", &construct , RC_NiAutoNormalParticles }, + { "NiCamera", &construct , RC_NiCamera }, + { "RootCollisionNode", &construct , RC_RootCollisionNode }, + { "NiTexturingProperty", &construct , RC_NiTexturingProperty }, + { "NiMaterialProperty", &construct , RC_NiMaterialProperty }, + { "NiZBufferProperty", &construct , RC_NiZBufferProperty }, + { "NiAlphaProperty", &construct , RC_NiAlphaProperty }, + { "NiVertexColorProperty", &construct , RC_NiVertexColorProperty }, + { "NiShadeProperty", &construct , RC_NiShadeProperty }, + { "NiDitherProperty", &construct , RC_NiDitherProperty }, + { "NiWireframeProperty", &construct , RC_NiWireframeProperty }, + { "NiSpecularProperty", &construct , RC_NiSpecularProperty }, + { "NiStencilProperty", &construct , RC_NiStencilProperty }, + { "NiVisController", &construct , RC_NiVisController }, + { "NiGeomMorpherController", &construct , RC_NiGeomMorpherController }, + { "NiKeyframeController", &construct , RC_NiKeyframeController }, + { "NiAlphaController", &construct , RC_NiAlphaController }, + { "NiUVController", &construct , RC_NiUVController }, + { "NiPathController", &construct , RC_NiPathController }, + { "NiMaterialColorController", &construct , RC_NiMaterialColorController }, + { "NiBSPArrayController", &construct , RC_NiBSPArrayController }, + { "NiParticleSystemController", &construct , RC_NiParticleSystemController }, + { "NiAmbientLight", &construct , RC_NiLight }, + { "NiDirectionalLight", &construct , RC_NiLight }, + { "NiTextureEffect", &construct , RC_NiTextureEffect }, + { "NiVertWeightsExtraData", &construct , RC_NiVertWeightsExtraData }, + { "NiTextKeyExtraData", &construct , RC_NiTextKeyExtraData }, + { "NiStringExtraData", &construct , RC_NiStringExtraData }, + { "NiGravity", &construct , RC_NiGravity }, + { "NiPlanarCollider", &construct , RC_NiPlanarCollider }, + { "NiParticleGrowFade", &construct , RC_NiParticleGrowFade }, + { "NiParticleColorModifier", &construct , RC_NiParticleColorModifier }, + { "NiParticleRotation", &construct , RC_NiParticleRotation }, + { "NiFloatData", &construct , RC_NiFloatData }, + { "NiTriShapeData", &construct , RC_NiTriShapeData }, + { "NiVisData", &construct , RC_NiVisData }, + { "NiColorData", &construct , RC_NiColorData }, + { "NiPixelData", &construct , RC_NiPixelData }, + { "NiMorphData", &construct , RC_NiMorphData }, + { "NiKeyframeData", &construct , RC_NiKeyframeData }, + { "NiSkinData", &construct , RC_NiSkinData }, + { "NiUVData", &construct , RC_NiUVData }, + { "NiPosData", &construct , RC_NiPosData }, + { "NiRotatingParticlesData", &construct , RC_NiRotatingParticlesData }, + { "NiAutoNormalParticlesData", &construct , RC_NiAutoNormalParticlesData }, + { "NiSequenceStreamHelper", &construct , RC_NiSequenceStreamHelper }, + { "NiSourceTexture", &construct , RC_NiSourceTexture }, + { "NiSkinInstance", &construct , 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 where we stash all the functions we couldn't add as inline definitions in the record types. @@ -223,88 +318,15 @@ void NIFFile::parse() std::string rec = nif.getString(); - /* 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. - */ - - // 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 + RecordFactoryEntry const * entry = lookupRecordFactory (rec.c_str ()); + + if (entry != NULL) + { + r = entry->mCreate (); + r->recType = entry->mType; + } else - fail("Unknown record type " + rec); + fail("Unknown record type " + rec); assert(r != NULL); assert(r->recType != RC_MISSING);