From 8436dff732badfb3f98e109e24058005fc4a78d2 Mon Sep 17 00:00:00 2001 From: Marc Chapman Date: Wed, 26 Jul 2017 21:49:45 +0100 Subject: [PATCH] enhanced-field-mgmt -- Enhancements to dynamic field handling that allow for name filtering and replacement limiting --- Engine/source/console/simFieldDictionary.cpp | 64 +++++++++++++++++++- Engine/source/console/simFieldDictionary.h | 7 +++ Engine/source/console/simObject.cpp | 17 ++++++ Engine/source/console/simObject.h | 5 ++ 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/Engine/source/console/simFieldDictionary.cpp b/Engine/source/console/simFieldDictionary.cpp index 9615c59d0..7cf3deb94 100644 --- a/Engine/source/console/simFieldDictionary.cpp +++ b/Engine/source/console/simFieldDictionary.cpp @@ -20,6 +20,10 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// +// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames +// Copyright (C) 2015 Faust Logic, Inc. +//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// #include "platform/platform.h" #include "console/simFieldDictionary.h" @@ -361,4 +365,62 @@ SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator++() SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator*() { return(mEntry); -} \ No newline at end of file +} +// A variation of the stock SimFieldDictionary::setFieldValue(), this method adds the +// argument which, when true, prohibits the replacement of fields that +// already have a value. +// +// AFX uses this when an effects-choreographer (afxMagicSpell, afxEffectron) is created +// using the new operator. It prevents any in-line effect parameters from being overwritten +// by default parameters that are copied over later. +void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *value, ConsoleBaseType *type, bool no_replace) +{ + if (!no_replace) + { + setFieldValue(slotName, value); + return; + } + + if (!value || !*value) + return; + + U32 bucket = getHashValue(slotName); + Entry **walk = &mHashTable[bucket]; + while(*walk && (*walk)->slotName != slotName) + walk = &((*walk)->next); + + Entry *field = *walk; + if (field) + return; + + addEntry( bucket, slotName, type, dStrdup( value ) ); +} +// A variation of the stock SimFieldDictionary::assignFrom(), this method adds +// and arguments. When true, prohibits the replacement of fields that already +// have a value. When is specified, only fields with leading characters that exactly match +// the characters in are copied. +void SimFieldDictionary::assignFrom(SimFieldDictionary *dict, const char* filter, bool no_replace) +{ + dsize_t filter_len = (filter) ? dStrlen(filter) : 0; + if (filter_len == 0 && !no_replace) + { + assignFrom(dict); + return; + } + + mVersion++; + + if (filter_len == 0) + { + for(U32 i = 0; i < HashTableSize; i++) + for(Entry *walk = dict->mHashTable[i];walk; walk = walk->next) + setFieldValue(walk->slotName, walk->value, walk->type, no_replace); + } + else + { + for(U32 i = 0; i < HashTableSize; i++) + for(Entry *walk = dict->mHashTable[i];walk; walk = walk->next) + if (dStrncmp(walk->slotName, filter, filter_len) == 0) + setFieldValue(walk->slotName, walk->value, walk->type, no_replace); + } +} diff --git a/Engine/source/console/simFieldDictionary.h b/Engine/source/console/simFieldDictionary.h index bc865398c..4849be563 100644 --- a/Engine/source/console/simFieldDictionary.h +++ b/Engine/source/console/simFieldDictionary.h @@ -20,6 +20,11 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// +// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames +// Copyright (C) 2015 Faust Logic, Inc. +//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// + #ifndef _SIMFIELDDICTIONARY_H_ #define _SIMFIELDDICTIONARY_H_ @@ -90,6 +95,8 @@ public: U32 getNumFields() const { return mNumFields; } Entry *operator[](U32 index); + void setFieldValue(StringTableEntry slotName, const char *value, ConsoleBaseType *type, bool no_replace); + void assignFrom(SimFieldDictionary *dict, const char* filter, bool no_replace); }; class SimFieldDictionaryIterator diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index b1dbb8f13..c12a12f19 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -24,6 +24,7 @@ // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames // Copyright (C) 2015 Faust Logic, Inc. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// + #include "platform/platform.h" #include "platform/platformMemory.h" #include "console/simObject.h" @@ -52,6 +53,7 @@ ConsoleDocClass( SimObject, bool SimObject::smForceId = false; SimObjectId SimObject::smForcedId = 0; +bool SimObject::preventNameChanging = false; namespace Sim { @@ -221,6 +223,19 @@ String SimObject::describeSelf() const return desc; } +// Copies dynamic fields from one object to another, optionally limited by the settings for +// and . When true, prohibits the replacement of fields that +// already have a value. When is specified, only fields with leading characters that +// exactly match the characters in are copied. +void SimObject::assignDynamicFieldsFrom(SimObject* from, const char* filter, bool no_replace) +{ + if (from->mFieldDictionary) + { + if( mFieldDictionary == NULL ) + mFieldDictionary = new SimFieldDictionary; + mFieldDictionary->assignFrom(from->mFieldDictionary, filter, no_replace); + } +} //============================================================================= // Persistence. //============================================================================= @@ -2185,6 +2200,8 @@ bool SimObject::setProtectedParent( void *obj, const char *index, const char *da bool SimObject::setProtectedName(void *obj, const char *index, const char *data) { + if (preventNameChanging) + return false; SimObject *object = static_cast(obj); if ( object->isProperlyAdded() ) diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index 1261afd55..2119ea6a9 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -980,6 +980,11 @@ public: /*C*/ SimObject(const SimObject&, bool = false); bool isTempClone() const { return is_temp_clone; } virtual bool allowSubstitutions() const { return false; } + +public: + static bool preventNameChanging; + void assignDynamicFieldsFrom(SimObject*, const char* filter, bool no_replace=false); + public: virtual void reloadReset() { } };