| 981 | //----------------------------------------------------------------------------- |
| 982 | |
| 983 | void SimObject::setDataField(StringTableEntry slotName, const char *array, const char *value) |
| 984 | { |
| 985 | // first search the static fields if enabled |
| 986 | if(mFlags.test(ModStaticFields)) |
| 987 | { |
| 988 | const AbstractClassRep::Field *fld = findField(slotName); |
| 989 | if(fld) |
| 990 | { |
| 991 | // Skip the special field types as they are not data. |
| 992 | if ( fld->type >= AbstractClassRep::ARCFirstCustomField ) |
| 993 | return; |
| 994 | |
| 995 | S32 array1 = array ? dAtoi(array) : 0; |
| 996 | |
| 997 | // Here we check to see if <this> is a datablock and if <value> |
| 998 | // starts with "$$". If both true than save value as a runtime substitution. |
| 999 | if (dynamic_cast<SimDataBlock*>(this) && value[0] == '$' && value[1] == '$') |
| 1000 | { |
| 1001 | if (!this->allowSubstitutions()) |
| 1002 | { |
| 1003 | Con::errorf("Substitution Error: %s datablocks do not allow \"$$\" field substitutions. [%s]", |
| 1004 | this->getClassName(), this->getName()); |
| 1005 | return; |
| 1006 | } |
| 1007 | |
| 1008 | if (fld->doNotSubstitute) |
| 1009 | { |
| 1010 | Con::errorf("Substitution Error: field \"%s\" of datablock %s prohibits \"$$\" field substitutions. [%s]", |
| 1011 | slotName, this->getClassName(), this->getName()); |
| 1012 | return; |
| 1013 | } |
| 1014 | |
| 1015 | // add the substitution |
| 1016 | ((SimDataBlock*)this)->addSubstitution(slotName, array1, value); |
| 1017 | return; |
| 1018 | } |
| 1019 | |
| 1020 | if(array1 >= 0 && array1 < fld->elementCount && fld->elementCount >= 1) |
| 1021 | { |
| 1022 | // If the set data notify callback returns true, then go ahead and |
| 1023 | // set the data, otherwise, assume the set notify callback has either |
| 1024 | // already set the data, or has deemed that the data should not |
| 1025 | // be set at all. |
| 1026 | FrameTemp<char> buffer(2048); |
| 1027 | FrameTemp<char> bufferSecure(2048); // This buffer is used to make a copy of the data |
| 1028 | // so that if the prep functions or any other functions use the string stack, the data |
| 1029 | // is not corrupted. |
| 1030 | |
| 1031 | ConsoleBaseType *cbt = ConsoleBaseType::getType( fld->type ); |
| 1032 | AssertFatal( cbt != NULL, "Could not resolve Type Id." ); |
| 1033 | |
| 1034 | const char* szBuffer = cbt->prepData( value, buffer, 2048 ); |
| 1035 | dMemset( bufferSecure, 0, 2048 ); |
| 1036 | dMemcpy( bufferSecure, szBuffer, dStrlen( szBuffer ) ); |
| 1037 | |
| 1038 | if( (*fld->setDataFn)( this, array, bufferSecure ) ) |
| 1039 | Con::setData(fld->type, (void *) (((const char *)this) + fld->offset), array1, 1, &value, fld->table); |
| 1040 | |