GameMonkey Script

GameMonkey Script Forums
It is currently Fri May 24, 2019 7:29 pm

All times are UTC

Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Mon Aug 13, 2007 10:09 pm 

Joined: Sun Jul 29, 2007 11:52 am
Posts: 33
Location: Canberra, Australia
Hey again, just been getting some more stuff added to my engine to start interfacing the physics and scripting system.

I also got a little bored and decided to do a little bruteforce test on gamemonkey, see if it could cope. Creating 10000 Vector3s ever 0.05 seconds inside a simple loop I'm using to test the physics interface:

global makeBall = function()
   this:Body_SetGeoSphere( 128.0, 28.0 );
   local SpinCount = 0.0;
   sleep( 2.0f );

   local test;
   while( 1 )
      // make some crappy objects
      for( i = 0; i < 10000; i = i + 1 )
         test = Vector3( 10, 10, 10 );

      local XForce = sin( SpinCount ) * 4096.0;
      local YForce = -cos( SpinCount ) * 4096.0;
      this:Body_ApplyForce( XForce, 0.0, YForce );
      SpinCount += 0.05;
      sleep( 0.05 );

That is the function I'm using. Even without that for loop of 10,000 inside of the while, but before the while, I get this problem...

Anyways, the problem I'm having...

I've got a door entity also existing in the world, which is triggered to open and close. I have two triggers, one setup to open, one to close, by means of a message, the code for these as follows:

// trigger_once
global TriggerOnce_OnProcess = function()
   local Time_ = .triggertime.Float();   
   local Message_ = .message;
   local Target_ = Ent_FindEntity( .target );   
   if( Target_ != null )
      sleep( Time_ );
      Target_:Ent_SendMessage( Message_ );

The actual problem appears to happen after creation of many Vector3s, and will occur in a call to C++ from these functions:

global Ent_MoveTo = function( Position, Time )
   this:Ent_MoveToAsync( Position, Time );
   sleep( Time );

global FuncDoor_OnMessage = function( Message )
   if( Message == "open" )
      // Open
      this:Ent_MoveTo( .OpenPos_, .OpenTime_ );
      // If we have an autoclose time, wait, then close.
      if( .AutoCloseTime_ > 0.0 )
         sleep( .AutoCloseTime_ );      
         this:Ent_MoveTo( .ClosePos_, .CloseTime_ );
   else if( Message == "close" )
      // Close
      this:Ent_MoveTo( .ClosePos_, .CloseTime_ );

Ent_MoveToAsync just sets the state in an entity to tell it to move to a position within a set time period in seconds.

This function in C++ is:

// scriptMoveTo
int GM_CDECL EntScriptable::scriptMoveTo( gmThread* a_thread )
   // 0 - Position
   // 1 - Time
   GM_CHECK_USER_PARAM( BcVec3d* , GM_VECTOR3, pPosition, 0 );

   EntScriptable* pThis = reinterpret_cast< EntScriptable* >( a_thread->ThisUser() );
   BcAssert( pThis != NULL );

   pThis->bMoveTo_ = BcTrue;
   pThis->MoveToStart_ = pThis->Position_;
   pThis->MoveToEnd_ = *pPosition;
   pThis->MoveToTime_ = Time;
   pThis->MoveToTick_ = 0.0f;

   return GM_OK;

GM_CHECK_USER_PARAM( BcVec3d* , GM_VECTOR3, pPosition, 0 ); will fail - and spit out this to the console:

"expecting param 0 as user type 7"

The type is actually "0", GM_NULL. Is the garbage collector collecting perfectly valid objects which are members of a user type? The "this" of my FuncDoor is a usertype, which also points directly back to a table. It is also a global variable set by:

pMachine->GetGlobals()->Set( pMachine, pFileData->pProps_[ i ].Value_, ThisVar );

"ThisVar" is the user object which is the entity, "pFileData->pProps_[ i ].Value_" is the entity name.

I get the feeling that I am forgetting something if garbage collection is clearing up some of my lovely objects :(
Anyone know if I am, or could anyone point me roughly in the right direction to start tracking this tricky little bug?


PS: Just tried replacing that nasty for loop of creational doom with "sysCollectGarbage( true );", same bug occurs.

PSS: I found the solution...was a little obvious really, but I'll post it incase someone end has a similar bug to me:

// Ctor
   bRunning_( BcFalse )
   gmMachine* pMachine = GmManager::instance().pMachine();

   pTableObject_ = pMachine->AllocTableObject();
   pUserObject_ = pMachine->AllocUserObject( this, EntScriptable::TypeID_ );

   // Make sure the garbage collector doesn't remove them from us.
   pMachine->AddCPPOwnedGMObject( pTableObject_ );
   pMachine->AddCPPOwnedGMObject( pUserObject_ );

   Position_.set( 0.0f, 0.0f, 0.0f );
   Orientation_.set( 0.0f, 0.0f, 0.0f, 1.0f );

   bMoveTo_ = BcFalse;
   bRotateTo_ = BcFalse;

I was forgetting to call AddCPPOwnedGMObject - The tables containing the variables that became null were being binned. They are not anymore however 8)

Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC

Who is online

Users browsing this forum: No registered users and 2 guests

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group