fieldBrushObject.cpp
Engine/source/console/fieldBrushObject.cpp
Public Defines
define
INTERNAL_FIELD_PREFIX() "_fieldBrush_"
Public Variables
char
replacebuf [1024]
Public Functions
ConsoleDocClass(FieldBrushObject , "@brief For static-field copying/ pasting, editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only\n\n</a>" " @internal" )
DefineEngineMethod(FieldBrushObject , copyFields , void , (const char *simObjName, const char *pFieldList) , ("") , "(simObject, [fieldList]) Copy selected static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> copy static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from.\n</a>" "@param fieldList fields <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">against.\n</a>" "@return No return value." )
DefineEngineMethod(FieldBrushObject , pasteFields , void , (const char *simObjName) , "(simObject) Paste copied static-fields <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> paste static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to.\n</a>" "@return No return value." )
DefineEngineMethod(FieldBrushObject , queryFields , const char * , (const char *simObjName, const char *groupList) , ("") , "(simObject, [groupList]) Query available static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> query static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">on.\n</a>" "@param groupList groups <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">against.\n</a>" "@return Space-seperated static-field list." )
DefineEngineMethod(FieldBrushObject , queryGroups , const char * , (const char *simObjName) , "(simObject) Query available static-field groups <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> query static-field groups <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">on.\n</a>" "@return Space-seperated static-field group list." )
char *
suppressSpaces(const char * in_pname)
Detailed Description
Public Defines
INTERNAL_FIELD_PREFIX() "_fieldBrush_"
Public Variables
const U32 bufferSizes
char replacebuf [1024]
Public Functions
ConsoleDocClass(FieldBrushObject , "@brief For static-field copying/ pasting, editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only\n\n</a>" " @internal" )
DefineEngineMethod(FieldBrushObject , copyFields , void , (const char *simObjName, const char *pFieldList) , ("") , "(simObject, [fieldList]) Copy selected static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> copy static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from.\n</a>" "@param fieldList fields <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">against.\n</a>" "@return No return value." )
DefineEngineMethod(FieldBrushObject , pasteFields , void , (const char *simObjName) , "(simObject) Paste copied static-fields <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> paste static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">to.\n</a>" "@return No return value." )
DefineEngineMethod(FieldBrushObject , queryFields , const char * , (const char *simObjName, const char *groupList) , ("") , "(simObject, [groupList]) Query available static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> query static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">on.\n</a>" "@param groupList groups <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> filter static-fields <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">against.\n</a>" "@return Space-seperated static-field list." )
DefineEngineMethod(FieldBrushObject , queryGroups , const char * , (const char *simObjName) , "(simObject) Query available static-field groups <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> selected object./\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param simObject <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> query static-field groups <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">on.\n</a>" "@return Space-seperated static-field group list." )
IMPLEMENT_CONOBJECT(FieldBrushObject )
suppressSpaces(const char * in_pname)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "core/strings/stringUnit.h" 25#include "console/fieldBrushObject.h" 26#include "console/engineAPI.h" 27 28// Prefix added to dynamic-fields when they're used to store any copied static-fields when peristing. 29#define INTERNAL_FIELD_PREFIX "_fieldBrush_" 30 31// Size of return buffers used. 32const U32 bufferSizes = 1024 * 4; 33 34 35IMPLEMENT_CONOBJECT(FieldBrushObject); 36 37ConsoleDocClass( FieldBrushObject, 38 "@brief For static-field copying/pasting, editor use only\n\n" 39 "@internal" 40); 41 42FieldBrushObject::FieldBrushObject() 43{ 44 // Reset Description. 45 mDescription = StringTable->EmptyString(); 46 mSortName = StringTable->EmptyString(); 47} 48 49 50//----------------------------------------------------------------------------- 51// Persist Fields. 52//----------------------------------------------------------------------------- 53void FieldBrushObject::initPersistFields() 54{ 55 // Add Fields. 56 addProtectedField("description", TypeCaseString, Offset(mDescription, FieldBrushObject), setDescription, defaultProtectedGetFn, ""); 57 addProtectedField("sortName", TypeString, Offset(mSortName, FieldBrushObject), setSortName, defaultProtectedGetFn, ""); 58 59 // Call Parent. 60 Parent::initPersistFields(); 61} 62 63//----------------------------------------------------------------------------- 64// Remove from Sim. 65//----------------------------------------------------------------------------- 66void FieldBrushObject::onRemove() 67{ 68 // Destroy any fields. 69 destroyFields(); 70 71 // Call Parent. 72 Parent::onRemove(); 73} 74 75 76//----------------------------------------------------------------------------- 77// Destroy any fields. 78//----------------------------------------------------------------------------- 79void FieldBrushObject::destroyFields() 80{ 81 // Fetch Dynamic-Field Dictionary. 82 SimFieldDictionary* pFieldDictionary = getFieldDictionary(); 83 84 // Any Field Dictionary? 85 if ( pFieldDictionary == NULL ) 86 { 87 // No, so we're done. 88 return; 89 } 90 91 // Iterate fields. 92 for ( SimFieldDictionaryIterator itr(pFieldDictionary); *itr; ++itr ) 93 { 94 // Fetch Field Entry. 95 SimFieldDictionary::Entry* fieldEntry = *itr; 96 97 // Internal Field? 98 if ( dStrstr( fieldEntry->slotName, INTERNAL_FIELD_PREFIX ) == fieldEntry->slotName ) 99 { 100 // Yes, so remove it. 101 pFieldDictionary->setFieldValue( fieldEntry->slotName, "" ); 102 } 103 } 104} 105 106 107//----------------------------------------------------------------------------- 108// Suppress Spaces. 109//----------------------------------------------------------------------------- 110static char replacebuf[1024]; 111static char* suppressSpaces(const char* in_pname) 112{ 113 U32 i = 0; 114 char chr; 115 do 116 { 117 chr = in_pname[i]; 118 replacebuf[i++] = (chr != 32) ? chr : '_'; 119 } while(chr); 120 121 return replacebuf; 122} 123 124//----------------------------------------------------------------------------- 125// Query Groups. 126//----------------------------------------------------------------------------- 127DefineEngineMethod(FieldBrushObject, queryGroups, const char*, (const char* simObjName), , "(simObject) Query available static-field groups for selected object./\n" 128 "@param simObject Object to query static-field groups on.\n" 129 "@return Space-seperated static-field group list.") 130{ 131 // Fetch selected object. 132 SimObject* pSimObject = dynamic_cast<SimObject*>( Sim::findObject( simObjName ) ); 133 134 // Valid object? 135 if ( pSimObject == NULL ) 136 { 137 // No, so warn. 138 Con::warnf("FieldBrushObject::queryFieldGroups() - Invalid SimObject!"); 139 return NULL; 140 } 141 142 // Create Returnable Buffer. 143 S32 maxBuffer = bufferSizes; 144 char* pReturnBuffer = Con::getReturnBuffer(bufferSizes); 145 char* pBuffer = pReturnBuffer; 146 147 // Fetch Field List. 148 const AbstractClassRep::FieldList& staticFields = pSimObject->getFieldList(); 149 150 // Iterate Fields. 151 for( U32 fieldIndex = 0; fieldIndex < staticFields.size(); ++fieldIndex ) 152 { 153 // Fetch Field. 154 const AbstractClassRep::Field& staticField = staticFields[fieldIndex]; 155 156 // Start Group? 157 if ( staticField.type == AbstractClassRep::StartGroupFieldType ) 158 { 159 // Yes, so write-out group-name without spaces... 160 char* pGroupNameNoSpaces = suppressSpaces(staticField.pGroupname); 161 162 // Will the field fit? 163 // NOTE:- We used "-1" to include the suffix space. 164 if ( (maxBuffer - (S32)dStrlen(pGroupNameNoSpaces) - 1) >= 0 ) 165 { 166 // Yes... 167 // NOTE:- The group-name does not have the "_begingroup" suffix which should stay hidden. 168 S32 charsWritten = dSprintf( pBuffer, maxBuffer, "%s ", pGroupNameNoSpaces ); 169 pBuffer += charsWritten; 170 maxBuffer -= charsWritten; 171 } 172 else 173 { 174 // No, so warn. 175 Con::warnf("FieldBrushObject::queryGroups() - Couldn't fit all groups into return string!"); 176 break; 177 } 178 } 179 } 180 181 // Strip final space. 182 if ( pBuffer != pReturnBuffer ) 183 { 184 *(pBuffer-1) = 0; 185 } 186 187 // Return Buffer. 188 return pReturnBuffer; 189} 190 191 192//----------------------------------------------------------------------------- 193// Query Fields. 194//----------------------------------------------------------------------------- 195DefineEngineMethod(FieldBrushObject, queryFields, const char*, (const char* simObjName, const char* groupList), (""), "(simObject, [groupList]) Query available static-fields for selected object./\n" 196 "@param simObject Object to query static-fields on.\n" 197 "@param groupList groups to filter static-fields against.\n" 198 "@return Space-seperated static-field list.") 199{ 200 // Fetch selected object. 201 SimObject* pSimObject = dynamic_cast<SimObject*>( Sim::findObject( simObjName ) ); 202 203 // Valid object? 204 if ( pSimObject == NULL ) 205 { 206 // No, so warn. 207 Con::warnf("FieldBrushObject::queryFields() - Invalid SimObject!"); 208 return NULL; 209 } 210 211 // Create Returnable Buffer. 212 S32 maxBuffer = bufferSizes; 213 char* pReturnBuffer = Con::getReturnBuffer(bufferSizes); 214 char* pBuffer = pReturnBuffer; 215 216 // Fetch Field List. 217 const AbstractClassRep::FieldList& staticFields = pSimObject->getFieldList(); 218 219 // Did we specify a groups list? 220 if ( String::isEmpty(groupList) ) 221 { 222 // No, so return all fields... 223 224 // Iterate fields. 225 for( U32 fieldIndex = 0; fieldIndex < staticFields.size(); ++fieldIndex ) 226 { 227 // Fetch Field. 228 const AbstractClassRep::Field& staticField = staticFields[fieldIndex]; 229 230 // Standard Field? 231 if ( staticField.type != AbstractClassRep::StartGroupFieldType && 232 staticField.type != AbstractClassRep::EndGroupFieldType && 233 staticField.type != AbstractClassRep::DeprecatedFieldType ) 234 { 235 // Yes, so will the field fit? 236 // NOTE:- We used "-1" to include the suffix space. 237 if ( (maxBuffer - (S32)dStrlen(staticField.pFieldname) - 1) >= 0 ) 238 { 239 // Yes, so write-out field-name. 240 S32 charsWritten = dSprintf( pBuffer, maxBuffer, "%s ", staticField.pFieldname ); 241 pBuffer += charsWritten; 242 maxBuffer -= charsWritten; 243 } 244 else 245 { 246 // No, so warn. 247 Con::warnf("FieldBrushObject::queryFields() - Couldn't fit all fields into return string!"); 248 break; 249 } 250 } 251 } 252 253 // Strip final space. 254 if ( pBuffer != pReturnBuffer ) 255 { 256 *(pBuffer-1) = 0; 257 } 258 259 // Return field list. 260 return pReturnBuffer; 261 } 262 263 // Yes, so filter by groups... 264 265 // Group List. 266 Vector<StringTableEntry> groups; 267 // Yes, so fetch group list. 268 // Yes, so calculate group Count. 269 const U32 groupCount = StringUnit::getUnitCount( groupList, " \t\n" ); 270 271 char tempBuf[256]; 272 273 // Iterate groups... 274 for ( U32 groupIndex = 0; groupIndex < groupCount; ++groupIndex ) 275 { 276 // Copy string element. 277 dStrcpy( tempBuf, StringUnit::getUnit( groupList, groupIndex, " \t\n" ), 256 ); 278 // Append internal name. 279 dStrcat( tempBuf, "_begingroup", 256 ); 280 // Store Group. 281 groups.push_back( StringTable->insert( tempBuf ) ); 282 } 283 284 // Reset Valid Group. 285 bool validGroup = false; 286 287 // Iterate fields. 288 for( U32 fieldIndex = 0; fieldIndex < staticFields.size(); ++fieldIndex ) 289 { 290 // Fetch Field. 291 const AbstractClassRep::Field& staticField = staticFields[fieldIndex]; 292 293 // Handle Group Type. 294 switch( staticField.type ) 295 { 296 // Start Group. 297 case AbstractClassRep::StartGroupFieldType: 298 { 299 // Is this group valid? 300 301 // Iterate groups... 302 for ( U32 groupIndex = 0; groupIndex < groups.size(); ++groupIndex ) 303 { 304 // Group selected? 305 if ( groups[groupIndex] == staticField.pFieldname ) 306 { 307 // Yes, so flag as valid. 308 validGroup = true; 309 break; 310 } 311 } 312 313 } break; 314 315 // End Group. 316 case AbstractClassRep::EndGroupFieldType: 317 { 318 // Reset Valid Group. 319 validGroup = false; 320 321 } break; 322 323 // Deprecated. 324 case AbstractClassRep::DeprecatedFieldType: 325 { 326 } break; 327 328 // Standard. 329 default: 330 { 331 // Do we have a valid group? 332 if ( validGroup ) 333 { 334 // Yes, so will the field fit? 335 // NOTE:- We used "-1" to include the suffix space. 336 if ( (maxBuffer - (S32)dStrlen(staticField.pFieldname) - 1) >= 0 ) 337 { 338 // Yes, so write-out field-name. 339 S32 charsWritten = dSprintf( pBuffer, maxBuffer, "%s ", staticField.pFieldname ); 340 pBuffer += charsWritten; 341 maxBuffer -= charsWritten; 342 } 343 else 344 { 345 // No, so warn. 346 Con::warnf("FieldBrushObject::queryFields() - Couldn't fit all fields into return string!"); 347 // HACK: Easy way to finish iterating fields. 348 fieldIndex = staticFields.size(); 349 break; 350 } 351 } 352 353 } break; 354 }; 355 } 356 357 // Strip final space. 358 if ( pBuffer != pReturnBuffer ) 359 { 360 *(pBuffer-1) = 0; 361 } 362 363 // Return field list. 364 return pReturnBuffer; 365} 366 367//----------------------------------------------------------------------------- 368// Copy Fields. 369//----------------------------------------------------------------------------- 370DefineEngineMethod(FieldBrushObject, copyFields, void, (const char* simObjName, const char* pFieldList), (""), "(simObject, [fieldList]) Copy selected static-fields for selected object./\n" 371 "@param simObject Object to copy static-fields from.\n" 372 "@param fieldList fields to filter static-fields against.\n" 373 "@return No return value.") 374{ 375 // Fetch selected object. 376 SimObject* pSimObject = dynamic_cast<SimObject*>( Sim::findObject( simObjName ) ); 377 378 // Valid object? 379 if ( pSimObject == NULL ) 380 { 381 // No, so warn. 382 Con::warnf("FieldBrushObject::copyFields() - Invalid SimObject!"); 383 return; 384 } 385 386 // Fetch field list. 387 388 // Copy Fields. 389 object->copyFields( pSimObject, pFieldList ); 390} 391// Copy Fields. 392void FieldBrushObject::copyFields( SimObject* pSimObject, const char* fieldList ) 393{ 394 // FieldBrushObject class? 395 if ( String::compare(pSimObject->getClassName(), getClassName()) == 0 ) 396 { 397 // Yes, so warn. 398 Con::warnf("FieldBrushObject::copyFields() - Cannot copy FieldBrushObject objects!"); 399 return; 400 } 401 402 char tempBuf[bufferSizes]; 403 404 // Field List. 405 Vector<StringTableEntry> fields; 406 407 // Fetch valid field-list flag. 408 bool validFieldList = ( fieldList != NULL ); 409 410 // Did we specify a fields list? 411 if ( validFieldList ) 412 { 413 // Yes, so calculate field Count. 414 const U32 fieldCount = StringUnit::getUnitCount( fieldList, " \t\n" ); 415 416 // Iterate fields... 417 for ( U32 fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex ) 418 { 419 // Copy string element. 420 dStrcpy( tempBuf, StringUnit::getUnit( fieldList, fieldIndex, " \t\n" ), bufferSizes ); 421 422 // Store field. 423 fields.push_back( StringTable->insert( tempBuf ) ); 424 } 425 } 426 427 // Destroy Fields. 428 destroyFields(); 429 430 // Fetch Field List. 431 const AbstractClassRep::FieldList& staticFields = pSimObject->getFieldList(); 432 433 // Iterate fields. 434 for( U32 fieldIndex = 0; fieldIndex < staticFields.size(); ++fieldIndex ) 435 { 436 // Fetch Field. 437 const AbstractClassRep::Field& staticField = staticFields[fieldIndex]; 438 439 // Standard Field? 440 if ( staticField.type != AbstractClassRep::StartGroupFieldType && 441 staticField.type != AbstractClassRep::EndGroupFieldType && 442 staticField.type != AbstractClassRep::DeprecatedFieldType ) 443 { 444 // Set field-specified flag. 445 bool fieldSpecified = !validFieldList; 446 447 // Did we specify a fields list? 448 if ( validFieldList ) 449 { 450 // Yes, so is this field name selected? 451 452 // Iterate fields... 453 for ( U32 findFieldIDx = 0; findFieldIDx < fields.size(); ++findFieldIDx) 454 { 455 // Field selected? 456 if ( staticField.pFieldname == fields[findFieldIDx] ) 457 { 458 // Yes, so flag as such. 459 fieldSpecified = true; 460 break; 461 } 462 } 463 } 464 465 // Field specified? 466 if ( fieldSpecified ) 467 { 468 if ( staticField.elementCount <= 1 ) 469 { 470 for( U32 fieldElement = 0; S32(fieldElement) < staticField.elementCount; ++fieldElement ) 471 { 472 // Fetch Field Value. 473 const char* fieldValue = (staticField.getDataFn)( pSimObject, Con::getData(staticField.type, (void *) (((const char *)pSimObject) + staticField.offset), fieldElement, staticField.table, staticField.flag) ); 474 475 // Field Value? 476 if ( fieldValue ) 477 { 478 // Yes. 479 dSprintf( tempBuf, sizeof(tempBuf), INTERNAL_FIELD_PREFIX"%s", staticField.pFieldname ); 480 481 // Fetch Dynamic-Field Dictionary. 482 SimFieldDictionary* pFieldDictionary = getFieldDictionary(); 483 484 // Set field value. 485 if ( !pFieldDictionary ) 486 { 487 setDataField( StringTable->insert( tempBuf ), NULL, fieldValue ); 488 } 489 else 490 { 491 pFieldDictionary->setFieldValue( StringTable->insert( tempBuf ), fieldValue ); 492 } 493 } 494 } 495 } 496 } 497 } 498 } 499} 500 501//----------------------------------------------------------------------------- 502// Paste Fields. 503//----------------------------------------------------------------------------- 504DefineEngineMethod(FieldBrushObject, pasteFields, void, (const char* simObjName), , "(simObject) Paste copied static-fields to selected object./\n" 505 "@param simObject Object to paste static-fields to.\n" 506 "@return No return value.") 507{ 508 // Fetch selected object. 509 SimObject* pSimObject = dynamic_cast<SimObject*>( Sim::findObject( simObjName ) ); 510 511 // Valid object? 512 if ( pSimObject == NULL ) 513 { 514 // No, so warn. 515 Con::warnf("FieldBrushObject::pasteFields() - Invalid SimObject!"); 516 return; 517 } 518 519 // Paste Fields. 520 object->pasteFields( pSimObject ); 521} 522// Paste Fields. 523void FieldBrushObject::pasteFields( SimObject* pSimObject ) 524{ 525 // FieldBrushObject class? 526 if ( String::compare(pSimObject->getClassName(), getClassName()) == 0 ) 527 { 528 // Yes, so warn. 529 Con::warnf("FieldBrushObject::pasteFields() - Cannot paste FieldBrushObject objects!"); 530 return; 531 } 532 533 // Fetch Dynamic-Field Dictionary. 534 SimFieldDictionary* pFieldDictionary = getFieldDictionary(); 535 536 // Any Field Dictionary? 537 if ( pFieldDictionary == NULL ) 538 { 539 // No, so we're done. 540 return; 541 } 542 543 // Force modification of static-fields on target object! 544 pSimObject->setModStaticFields( true ); 545 546 S32 prefixLength = dStrlen(INTERNAL_FIELD_PREFIX); 547 548 // Iterate fields. 549 for ( SimFieldDictionaryIterator itr(pFieldDictionary); *itr; ++itr ) 550 { 551 // Fetch Field Entry. 552 SimFieldDictionary::Entry* fieldEntry = *itr; 553 554 // Internal Field? 555 char* pInternalField = dStrstr( fieldEntry->slotName, INTERNAL_FIELD_PREFIX ); 556 if ( pInternalField == fieldEntry->slotName ) 557 { 558 // Yes, so skip the prefix. 559 pInternalField += prefixLength; 560 561 // Is this a static-field on the target object? 562 // NOTE:- We're doing this so we don't end-up creating a dynamic-field if it isn't present. 563 564 // Fetch Field List. 565 const AbstractClassRep::FieldList& staticFields = pSimObject->getFieldList(); 566 567 // Iterate fields. 568 for( U32 fieldIndex = 0; fieldIndex < staticFields.size(); ++fieldIndex ) 569 { 570 // Fetch Field. 571 const AbstractClassRep::Field& staticField = staticFields[fieldIndex]; 572 573 // Standard Field? 574 if ( staticField.type != AbstractClassRep::StartGroupFieldType && 575 staticField.type != AbstractClassRep::EndGroupFieldType && 576 staticField.type != AbstractClassRep::DeprecatedFieldType ) 577 { 578 // Target field? 579 if ( String::compare(staticField.pFieldname, pInternalField) == 0 ) 580 { 581 // Yes, so set data. 582 pSimObject->setDataField( staticField.pFieldname, NULL, fieldEntry->value ); 583 } 584 } 585 } 586 } 587 } 588} 589