123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "console/simPersistSet.h"
- #include "console/simPersistID.h"
- #include "console/consoleTypes.h"
- #include "console/engineAPI.h"
- IMPLEMENT_CONOBJECT( SimPersistSet );
- ConsoleDocClass( SimPersistSet,
- "@brief A SimSet that can be safely persisted.\n\n"
- "Uses SimPersistIDs to reference objects in the set "
- "while persisted on disk. This allows the set to resolve "
- "its references no matter whether they are loaded before or "
- "after the set is created.\n\n"
- "Not intended for game development, for editors or internal use only.\n\n "
- "@internal");
- //-----------------------------------------------------------------------------
- SimPersistSet::SimPersistSet()
- : mIsResolvingPIDs( false )
- {
- VECTOR_SET_ASSOCIATION( mUnresolvedPIDs );
- }
- //-----------------------------------------------------------------------------
- bool SimPersistSet::processArguments( S32 argc, ConsoleValue *argv )
- {
- for( U32 i = 0; i < argc; ++ i )
- {
- // Parse the UUID.
- Torque::UUID uuid;
- if( !uuid.fromString( argv[ i ] ) )
- {
- Con::errorf( "SimPersistSet::processArguments - could not read UUID at index %i: %s", i, (const char*)argv[ i ] );
- continue;
- }
- // Find or create the respective persistent ID.
- SimPersistID* pid = SimPersistID::findOrCreate( uuid );
- if( pid->getObject() )
- {
- // There's already an object attached to this PID so just
- // add the object to the set.
- addObject( pid->getObject() );
- }
- else
- {
- // There not yet an object attached to the PID so push it
- // onto the stack to resolve it later.
- pid->incRefCount();
- mUnresolvedPIDs.push_back( pid );
- }
- }
- return true;
- }
- //-----------------------------------------------------------------------------
- void SimPersistSet::write( Stream& stream, U32 tabStop, U32 flags )
- {
- if( ( flags & SelectedOnly ) && !isSelected() )
- return;
-
- // If the selection is transient, we cannot really save it.
- // Just invoke the default SimObject::write and return.
-
- if( !getCanSave() )
- {
- Con::errorf( "SimPersistSet::write - transient set being saved: %d:%s (%s)",
- getId(), getClassName(), getName() );
- Parent::write( stream, tabStop, flags );
- return;
- }
-
- // If there are unresolved PIDs, give resolving them one last
- // chance before writing out the set.
-
- if( !mUnresolvedPIDs.empty() )
- resolvePIDs();
-
- // Write the set out.
- stream.writeTabs( tabStop );
-
- StringBuilder buffer;
- buffer.format( "new %s(%s", getClassName(), getName() ? getName() : "" );
-
- // Write the persistent IDs of all child objects into the set's
- // object constructor so we see them passed back to us through
- // processArguments when the object gets read in.
-
- const U32 numChildren = size();
- for( U32 i = 0; i < numChildren; ++ i )
- {
- SimObject* child = at( i );
-
- SimPersistID* pid = child->getPersistentId();
- AssertWarn( pid != NULL, "SimPersistSet::write - object without pid in persistent selection!" );
- if( !pid )
- continue;
-
- buffer.append( ',' );
- buffer.append( '"' );
- buffer.append( pid->getUUID().toString() );
- buffer.append( '"' );
- }
-
- buffer.append( ") {\r\n" );
- stream.write( buffer.length(), buffer.data() );
-
- // Write our object fields.
-
- writeFields( stream, tabStop + 1 );
-
- // Close our object definition.
- stream.writeTabs( tabStop );
- stream.write( 4, "};\r\n" );
- }
- //-----------------------------------------------------------------------------
- void SimPersistSet::resolvePIDs()
- {
- if( mIsResolvingPIDs )
- return;
- lock();
- mIsResolvingPIDs = true;
- for( U32 i = 0; i < mUnresolvedPIDs.size(); ++ i )
- if( mUnresolvedPIDs[ i ]->getObject() != NULL )
- {
- addObject( mUnresolvedPIDs[ i ]->getObject() );
- mUnresolvedPIDs[i]->decRefCount();
- mUnresolvedPIDs.erase( i );
- -- i;
- }
- mIsResolvingPIDs = false;
- unlock();
- }
- //-----------------------------------------------------------------------------
- void SimPersistSet::addObject( SimObject* object )
- {
- // If this set isn't transient, make sure the object has a valid
- // persistent ID.
-
- if( getCanSave() )
- object->getOrCreatePersistentId();
-
- Parent::addObject( object );
- }
- //=============================================================================
- // Console Methods.
- //=============================================================================
- // MARK: ---- Console Methods ----
- //-----------------------------------------------------------------------------
- DefineEngineMethod( SimPersistSet, resolvePersistentIds, void, (), , "() - Try to bind unresolved persistent IDs in the set." )
- {
- object->resolvePIDs();
- }
|