VObject.cpp

Engine/source/Verve/Core/VObject.cpp

More...

Public Functions

Detailed Description

Public Functions

IMPLEMENT_CONOBJECT(VObject )

  1
  2//-----------------------------------------------------------------------------
  3// Verve
  4// Copyright (C) 2014 - Violent Tulip
  5//
  6// Permission is hereby granted, free of charge, to any person obtaining a copy
  7// of this software and associated documentation files (the "Software"), to
  8// deal in the Software without restriction, including without limitation the
  9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10// sell copies of the Software, and to permit persons to whom the Software is
 11// furnished to do so, subject to the following conditions:
 12//
 13// The above copyright notice and this permission notice shall be included in
 14// all copies or substantial portions of the Software.
 15//
 16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 22// IN THE SOFTWARE.
 23//-----------------------------------------------------------------------------
 24#include "Verve/Core/VObject.h"
 25#include "Verve/Core/VController.h"
 26#include "console/consoleTypes.h"
 27
 28//-----------------------------------------------------------------------------
 29IMPLEMENT_CONOBJECT( VObject );
 30//-----------------------------------------------------------------------------
 31
 32VObject::VObject( void ) : 
 33        mController( NULL ),
 34        mLabel( String::EmptyString ),
 35        mEnabled( true )
 36{
 37    // Void.
 38};
 39
 40VObject::~VObject( void )
 41{
 42    // Remove.
 43    remove();
 44}
 45
 46void VObject::initPersistFields( void )
 47{
 48    // Don't Use Parent Fields.
 49    // Parent::initPersistFields();
 50
 51    addProtectedField( "Enabled", TypeBool,       Offset( mEnabled, VObject ), &setEnabled, &defaultProtectedGetFn, "Enable or Disable the object from playback." );
 52    addProtectedField( "Label",   TypeRealString, Offset( mLabel,   VObject ), &setLabel,   &defaultProtectedGetFn, "The label this object is referenced by." );
 53}
 54
 55//-----------------------------------------------------------------------------
 56//
 57// Reference Methods.
 58//
 59//-----------------------------------------------------------------------------
 60
 61//-----------------------------------------------------------------------------
 62// 
 63// VObject::getObject( pLabel );
 64// 
 65// Returns the object with the given label. If no object belongs to this object
 66// with that label, then a NULL value is returned.
 67// 
 68//-----------------------------------------------------------------------------
 69VObject *VObject::getObject( const String &pLabel )
 70{
 71    VObject *node = ( VObject* )mChildNode;
 72    while ( node )
 73    {
 74        // Compare Names.
 75        if ( node->getLabel().equal( pLabel, String::NoCase ) )
 76        {
 77            // Valid.
 78            return node;
 79        }
 80
 81        // Next Sibling.
 82        node = ( VObject* )node->mSiblingNextNode;
 83    }
 84
 85    // Invalid.
 86    return NULL;
 87}
 88
 89//-----------------------------------------------------------------------------
 90//
 91// Property Methods.
 92//
 93//-----------------------------------------------------------------------------
 94
 95//-----------------------------------------------------------------------------
 96// 
 97// VObject::isEnabled();
 98// 
 99// Returns whether this object is enabled.
100// 
101//-----------------------------------------------------------------------------
102bool VObject::isEnabled( void )
103{
104    VObject *parent = dynamic_cast<VObject*>( getParent() );
105    if ( parent && !parent->isEnabled() )
106    {
107        return false;
108    }
109
110    return mEnabled;
111}
112
113//-----------------------------------------------------------------------------
114// 
115// VObject::isControllerPlaying();
116// 
117// Returns whether the root controller is currently playing.
118// 
119//-----------------------------------------------------------------------------
120bool VObject::isControllerPlaying( void )
121{
122    if ( getController() )
123    {
124        return getController()->isPlaying();
125    }
126
127    return false;
128}
129
130//-----------------------------------------------------------------------------
131// 
132// VObject::isControllerPaused();
133// 
134// Returns whether the root controller is currently paused.
135// 
136//-----------------------------------------------------------------------------
137bool VObject::isControllerPaused( void )
138{
139    if ( getController() )
140    {
141        return getController()->isPaused();
142    }
143
144    return false;
145}
146
147//-----------------------------------------------------------------------------
148// 
149// VObject::isControllerStopped();
150// 
151// Returns whether the root controller is currently stopped.
152// 
153//-----------------------------------------------------------------------------
154bool VObject::isControllerStopped( void )
155{
156    if ( getController() )
157    {
158        return getController()->isStopped();
159    }
160
161    return true;
162}
163
164//-----------------------------------------------------------------------------
165// 
166// VObject::isControllerPlayingForward();
167// 
168// Returns whether the root controller is currently playing forward.
169// 
170//-----------------------------------------------------------------------------
171bool VObject::isControllerPlayingForward( void )
172{
173    if ( getController() )
174    {
175        return getController()->isPlayingForward();
176    }
177
178    return true;
179}
180
181//-----------------------------------------------------------------------------
182// 
183// VObject::isControllerLooping();
184// 
185// Returns whether the root controller is looping the sequence.
186// 
187//-----------------------------------------------------------------------------
188bool VObject::isControllerLooping( void )
189{
190    if ( getController() )
191    {
192        return getController()->isLooping();
193    }
194
195    return true;
196}
197
198//-----------------------------------------------------------------------------
199// 
200// VObject::getControllerTime();
201// 
202// Returns the current time of the root controller.
203// 
204//-----------------------------------------------------------------------------
205S32 VObject::getControllerTime( void )
206{
207    if ( getController() )
208    {
209        return getController()->getTime();
210    }
211
212    return 0;
213}
214
215//-----------------------------------------------------------------------------
216// 
217// VObject::getControllerTimeScale();
218// 
219// Returns the current timescale of the root controller.
220// 
221//-----------------------------------------------------------------------------
222F32 VObject::getControllerTimeScale( void )
223{
224    if ( getController() )
225    {
226        return getController()->getTimeScale();
227    }
228
229    return 1.f;
230}
231
232//-----------------------------------------------------------------------------
233// 
234// VObject::getControllerDuration();
235// 
236// Returns the duration of the root controller.
237// 
238//-----------------------------------------------------------------------------
239S32 VObject::getControllerDuration( void )
240{
241    if ( getController() )
242    {
243        return getController()->getDuration();
244    }
245
246    return 0;
247}
248
249//-----------------------------------------------------------------------------
250// 
251// VObject::setLabel( pLabel );
252// 
253// Set the label property.
254// 
255// If the project was built using the VT_EDITOR preprocessor argument, then the
256// label will not be changed if the target name is already used in the parent
257// object.
258// 
259//-----------------------------------------------------------------------------
260void VObject::setLabel( const String &pLabel )
261{
262#ifdef VT_EDITOR
263    if ( mParentNode )
264    {
265        // Empty Label?
266        if ( mLabel.isEmpty() )
267        {
268            // Set Uniqu Label.
269            setLabelUnique( pLabel );
270            return;
271        }
272
273        for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode )
274        {
275            if ( walk != this )
276            {
277                if ( pLabel == walk->getLabel() )
278                {
279                    // Exit.
280                    return;
281                }
282            }
283        }
284    }
285#endif
286
287    // Set Label.
288    mLabel = pLabel;
289}
290
291//-----------------------------------------------------------------------------
292// 
293// VObject::setLabelUnique( pLabel );
294// 
295// If the label that has been passed is already in use, then a new label will
296// be generated by appending an index to the label. For example: MyLabel
297// becomes MyLabel0 ... MyLabelN
298//
299//-----------------------------------------------------------------------------
300void VObject::setLabelUnique( const String &pLabel )
301{
302    if ( mParentNode && pLabel.isNotEmpty() )
303    {
304        for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode )
305        {
306            if ( walk != this )
307            {
308                if ( pLabel == walk->getLabel() )
309                {
310                    // Strip Trailing Number.
311                    S32 i = -1;
312                    String labelBase( String::GetTrailingNumber( pLabel, i ) );
313                    i++;
314
315                    // Construct New Name.
316                    String labelBuffer = String::ToString( "%s%d", labelBase.c_str(), i );
317
318                    // Set Name.
319                    setLabelUnique( labelBuffer );
320
321                    // Exit.
322                    return;
323                }
324            }
325        }
326    }
327
328    // Set Name.
329    mLabel = pLabel;
330}
331
332//-----------------------------------------------------------------------------
333//
334// Callback Methods.
335//
336//-----------------------------------------------------------------------------
337
338//-----------------------------------------------------------------------------
339// 
340// VObject::onAttach();
341// 
342// Callback made when this object is attached to another node.
343// 
344//-----------------------------------------------------------------------------
345void VObject::onAttach( void )
346{
347    VTreeNode::onAttach();
348
349    // Store Controller.
350    mController = dynamic_cast<VController*>( getRoot() );
351
352#ifdef VT_EDITOR
353    if ( isProperlyAdded() )
354    {
355        Con::executef( this, "onAttach" );
356    }
357#endif
358}
359
360//-----------------------------------------------------------------------------
361// 
362// VObject::onDetach();
363// 
364// Callback made when this object is detached from a parent node.
365// 
366//-----------------------------------------------------------------------------
367void VObject::onDetach( void )
368{
369    VTreeNode::onDetach();
370
371    // Clear Controller.
372    mController = NULL;
373
374#ifdef VT_EDITOR
375    if ( isProperlyAdded() )
376    {
377        Con::executef( this, "onDetach" );
378    }
379#endif
380}
381
382#ifdef VT_EDITOR
383//-----------------------------------------------------------------------------
384//
385// Debug Methods.
386//
387//-----------------------------------------------------------------------------
388
389DefineEngineMethod( VObject, writeFile, bool, (String fileName), (""), "( string pFileName ) - Save to a given filename.\n"
390                                               "@param pFileName The target file to write to.\n"
391                                               "@return Returns true if the write was successful." )
392{
393    // Write Target File.
394    return VPersistence::writeFile(fileName.c_str(), object );
395}
396
397DefineEngineMethod( VObject, readFile, bool, (String fileName), (""), "( string pFileName ) - Clears the object and loads the new data from the given filename.\n"
398                                              "@param pFileName The target file to read from.\n"
399                                              "@return Returns true if the read was successful." )
400{
401    // Read Target File.
402    return VPersistence::readFile(fileName.c_str(), object );
403}
404
405DefineEngineMethod( VObject, getRoot, S32, (),, "( void ) - Get the root object.\n"
406                                            "@return Returns the SimObjectId for the root object."  )
407{
408    // Fetch Object.
409    VObject *objectRef = ( VObject* )object->getRoot();
410
411    // Return Object ID.
412    return ( objectRef ) ? objectRef->getId() : 0;
413}
414
415DefineEngineMethod( VObject, getParent, S32, (),, "( void ) - Get the parent object.\n"
416                                              "@return Returns the SimObjectId for the parent object." )
417{
418    // Fetch Object.
419    VObject *objectRef = ( VObject* )object->mParentNode;
420
421    // Return Object ID.
422    return ( objectRef ) ? objectRef->getId() : 0;
423}
424
425DefineEngineMethod( VObject, getIndex, S32, (),, "( void ) - Get the index of this object relative to its siblings.\n"
426                                             "@return Returns the index of this object." )
427{
428    return object->getIndex();
429}
430
431DefineEngineMethod( VObject, getCount, S32, (),, "( void ) - Get the number of child objects.\n"
432                                             "@return Returns the number of child objects." )
433{
434    return object->size();
435}
436
437DefineEngineMethod( VObject, getObject, S32, (S32 index), (0), "( int pIndex ) - Get the object corresponding to the given index.\n"
438                                              "@param pIndex The index of the object you wish to retrieve.\n"
439                                              "@return Returns the SimObjectID for the object." )
440{
441    // Fetch Object.
442    VObject *objectRef = ( VObject* )object->at(index);
443
444    // Return Object ID.
445    return ( objectRef ) ? objectRef->getId() : 0;
446}
447
448DefineEngineMethod( VObject, clear, void, (),, "( void ) - Detaches and deletes all of the child objects.\n"
449                                           "@return No return value." )
450{
451    // Clear Sequence Lists.
452    object->clear();
453}
454
455DefineEngineMethod( VObject, addObject, void, (SimObject* simObj), (nullAsType<SimObject*>()), "( SimObject pObject ) - Add a child object to this node.\n"
456                                               "@param pObject The SimObjectID of the object to be added to this node.\n"
457                                               "@return No return value." )
458{
459   if (simObj == nullptr)
460      return;
461
462   VObject *child = dynamic_cast<VObject*>(simObj);
463    if ( child )
464    {
465        child->addTo( object );
466    }
467}
468
469DefineEngineMethod( VObject, removeObject, void, (SimObject* simObj), (nullAsType<SimObject*>()), "( SimObject pObject ) - Remove the target object from this node.\n"
470                                                  "@param pObject The SimObjectID of the object to be removed from this node.\n"
471                                                  "@return No return value." )
472{
473   if (simObj == nullptr)
474      return;
475
476   VObject *child = dynamic_cast<VObject*>(simObj);
477    if ( child && child->getParent() == object )
478    {
479        child->remove();
480    }
481}
482
483DefineEngineMethod( VObject, setLabelUnique, void, (String label), (""), "( string pLabel ) - Force this label to be unique.\n"
484                                                    "@param pLabel The name you wish to reference this object by.\n"
485                                                    "@return No return value." )
486{
487    // Set Label.
488    object->setLabelUnique(label);
489}
490#endif
491