Browse Source

- Added/Modified support for string-word accessors of "XYZW", "RGBA", "Width", "Height", "Count" & "_<value>".

The indice are as follows:

> X or R or Width = 0
> Y or G or Height = 1
> Z or B = 2
> W or A = 3"
> Count (gets the word count) e.g. "this is a test".count gets "4".
> _<value> gets the specific indexed word e.g. "this is a test"._3 gets the word "test".
MelvMay-GG 12 years ago
parent
commit
5330558904
1 changed files with 137 additions and 61 deletions
  1. 137 61
      engine/source/console/compiledEval.cc

+ 137 - 61
engine/source/console/compiledEval.cc

@@ -28,6 +28,7 @@
 #include "io/resource/resourceManager.h"
 
 #include "string/findMatch.h"
+#include "string/stringUnit.h"
 #include "console/consoleInternal.h"
 #include "io/fileStream.h"
 #include "console/compiler.h"
@@ -301,73 +302,148 @@ static void setUnit(const char *string, U32 index, const char *replace, const ch
    return;
 }
 
-// Gets a component of an object's field value or a variable and returns it
-// in val.
-static void getFieldComponent( SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField, char val[], S32 count )
+//-----------------------------------------------------------------------------
+
+static bool isDigitsOnly( const char* pString )
 {
-   const char* prevVal = NULL;
-   // Grab value from object.
-   if( object && field )
-      prevVal = object->getDataField( field, array );
-   // Otherwise, grab from the string stack. The value coming in will always
-   // be a string because that is how multicomponent variables are handled.
-   else
-      prevVal = STR.getStringValue();
+    // Sanity.
+    AssertFatal( pString != NULL, "isDigits() - Cannot check a NULL string." );
 
-   // Make sure we got a value.
-   if( prevVal && *prevVal )
-   {
-      // 'x', 'y', and 'z' grab the 1st, 2nd, or 3rd component of the
-      // variable or field.
-      if( subField == StringTable->insert( "x" ) )
-         getUnit( prevVal, 0, " ", val, count );
-      else if( subField == StringTable->insert( "y" ) )
-         getUnit( prevVal, 1, " ", val, count );
-      else if( subField == StringTable->insert( "z" ) )
-         getUnit( prevVal, 2, " ", val, count );
-   }
+    const char* pDigitCursor = pString;
+    if ( *pDigitCursor == 0 )
+        return false;
+
+    // Check for digits only.
+    do
+    {
+        if ( dIsdigit( *pDigitCursor++ ) )
+            continue;
+
+        return false;
+    }
+    while( *pDigitCursor != 0 );
+
+    return true;
 }
 
+//-----------------------------------------------------------------------------
+
+static const StringTableEntry _xyzw[] = 
+{
+    StringTable->insert( "x" ),
+    StringTable->insert( "y" ),
+    StringTable->insert( "z" ),
+    StringTable->insert( "w" )
+};
+
+static const StringTableEntry _rgba[] = 
+{
+    StringTable->insert( "r" ),
+    StringTable->insert( "g" ),
+    StringTable->insert( "b" ),
+    StringTable->insert( "a" )
+};
+
+static const StringTableEntry _size[] = 
+{
+    StringTable->insert( "width" ),
+    StringTable->insert( "height" )
+};
+
+static const StringTableEntry _count = StringTable->insert( "count" );
+
+//-----------------------------------------------------------------------------
+
+// Gets a component of an object's field value or a variable and returns it in val.
+static void getFieldComponent( SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField, FrameTemp<char>& val )
+{
+    const char* prevVal = NULL;
+   
+    // Grab value from object.
+    if( object && field )
+        prevVal = object->getDataField( field, array );
+   
+    // Otherwise, grab from the string stack. The value coming in will always
+    // be a string because that is how multicomponent variables are handled.
+    else
+        prevVal = STR.getStringValue();
+
+    // Make sure we got a value.
+    if ( prevVal && *prevVal )
+    {
+        if ( subField == _count )
+            dSprintf( val, val.getObjectCount(), "%d", StringUnit::getUnitCount( prevVal, " \t\n" ) );
+
+        else if ( subField == _xyzw[0] || subField == _rgba[0] || subField == _size[0] )
+            dStrcpy( val, StringUnit::getUnit( prevVal, 0, " \t\n") );
+
+        else if ( subField == _xyzw[1] || subField == _rgba[1] || subField == _size[1] )
+            dStrcpy( val, StringUnit::getUnit( prevVal, 1, " \t\n") );
+
+        else if ( subField == _xyzw[2] || subField == _rgba[2] )
+            dStrcpy( val, StringUnit::getUnit( prevVal, 2, " \t\n") );
+
+        else if ( subField == _xyzw[3] || subField == _rgba[3] )
+            dStrcpy( val, StringUnit::getUnit( prevVal, 3, " \t\n") );
+
+        else if ( *subField == '_' && isDigitsOnly(subField+1) )
+            dStrcpy( val, StringUnit::getUnit( prevVal, dAtoi(subField+1), " \t\n") );
+
+        else
+            val[0] = 0;
+    }
+    else
+        val[0] = 0;
+}
+
+//-----------------------------------------------------------------------------
+
 // Sets a component of an object's field value based on the sub field. 'x' will
 // set the first field, 'y' the second, and 'z' the third.
 static void setFieldComponent( SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField )
 {
-   char val[1024] = "";
-   const char* prevVal;
-   // Set the value on an object field.
-   if( object && field )
-      prevVal = object->getDataField( field, array );
-
-   // Set the value on a variable.
-   else if( gEvalState.currentVariable )
-      prevVal = gEvalState.getStringVariable();
-
-   // Insert the value into the specified component of the string.
-   bool set = false;
-   if( subField == StringTable->insert( "x" ) )
-   {
-      setUnit( prevVal, 0, STR.getStringValue(), " ", val, 1024 );
-      set = true;
-   }
-   else if( subField == StringTable->insert( "y" ) )
-   {
-      setUnit( prevVal, 1, STR.getStringValue(), " ", val, 1024 );
-      set = true;
-   }
-   else if( subField == StringTable->insert( "z" ) )
-   {
-      setUnit( prevVal, 2, STR.getStringValue(), " ", val, 1024 );
-      set = true;
-   }
+    // Copy the current string value
+    char strValue[1024];
+    dStrncpy( strValue, STR.getStringValue(), 1024 );
 
-   if( set )
-   {
-      // Update the field or variable.
-      if( object && field )
-         object->setDataField( field, array, val );
-      else if( gEvalState.currentVariable )
-         gEvalState.setStringVariable( val );
-   }
+    char val[1024] = "";
+    const char* prevVal = NULL;
+
+    // Set the value on an object field.
+    if( object && field )
+        prevVal = object->getDataField( field, array );
+
+    // Set the value on a variable.
+    else if( gEvalState.currentVariable )
+        prevVal = gEvalState.getStringVariable();
+
+    // Ensure that the variable has a value
+    if (!prevVal)
+	    return;
+
+    if ( subField == _xyzw[0] || subField == _rgba[0] || subField == _size[0] )
+	    dStrcpy( val, StringUnit::setUnit( prevVal, 0, strValue, " \t\n") );
+
+    else if ( subField == _xyzw[1] || subField == _rgba[1] || subField == _size[1] )
+        dStrcpy( val, StringUnit::setUnit( prevVal, 1, strValue, " \t\n") );
+
+    else if ( subField == _xyzw[2] || subField == _rgba[2] )
+        dStrcpy( val, StringUnit::setUnit( prevVal, 2, strValue, " \t\n") );
+
+    else if ( subField == _xyzw[3] || subField == _rgba[3] )
+        dStrcpy( val, StringUnit::setUnit( prevVal, 3, strValue, " \t\n") );
+
+    else if ( *subField == '_' && isDigitsOnly(subField+1) )
+        dStrcpy( val, StringUnit::setUnit( prevVal, dAtoi(subField+1), strValue, " \t\n") );
+
+    if ( val[0] != 0 )
+    {
+        // Update the field or variable.
+        if( object && field )
+            object->setDataField( field, 0, val );
+        else if( gEvalState.currentVariable )
+            gEvalState.setStringVariable( val );
+    }
 }
 
 const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
@@ -1160,7 +1236,7 @@ breakContinue:
             {
                // The field is not being retrieved from an object. Maybe it's
                // a special accessor?
-               getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer, VAL_BUFFER_SIZE );
+               getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer );
                intStack[UINT+1] = dAtoi( valBuffer );
             }
             UINT++;
@@ -1173,7 +1249,7 @@ breakContinue:
             {
                // The field is not being retrieved from an object. Maybe it's
                // a special accessor?
-               getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer, VAL_BUFFER_SIZE );
+               getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer );
                floatStack[FLT+1] = dAtof( valBuffer );
             }
             FLT++;
@@ -1189,7 +1265,7 @@ breakContinue:
             {
                // The field is not being retrieved from an object. Maybe it's
                // a special accessor?
-               getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer, VAL_BUFFER_SIZE );
+               getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer );
                STR.setStringValue( valBuffer );
             }