瀏覽代碼

enhanced-field-mgmt -- Enhancements to dynamic field handling that allow for name filtering and replacement limiting

Marc Chapman 8 年之前
父節點
當前提交
8436dff732

+ 63 - 1
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);
-}
+}
+// A variation of the stock SimFieldDictionary::setFieldValue(), this method adds the
+// <no_replace> 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 <no_replace>
+// and <filter> arguments. When true, <no_replace> prohibits the replacement of fields that already
+// have a value. When <filter> is specified, only fields with leading characters that exactly match
+// the characters in <filter> 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);
+   }
+}

+ 7 - 0
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

+ 17 - 0
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
+// <filter> and <no_replace>. When true, <no_replace> prohibits the replacement of fields that
+// already have a value. When <filter> is specified, only fields with leading characters that
+// exactly match the characters in <filter> 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<SimObject*>(obj);
    
    if ( object->isProperlyAdded() )

+ 5 - 0
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() { }
 };