Torque3D Documentation / _generateds / fieldBrushObject.cpp

fieldBrushObject.cpp

Engine/source/console/fieldBrushObject.cpp

More...

Public Defines

define
INTERNAL_FIELD_PREFIX() "_fieldBrush_"

Public Variables

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