GameMonkey Script

GameMonkey Script Forums
It is currently Tue Mar 19, 2019 7:53 pm

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Type Iterator mod
PostPosted: Tue Apr 07, 2009 12:13 pm 
Offline

Joined: Thu Jan 01, 2004 4:31 pm
Posts: 307
I've added the ability for a custom iterator across your own types. This is based off the table iterator and hooks into the BC_FOREACH code...

To implement, you need to create and register a gmTypeIteratorCallback with the machine for your user type.

Code:
bool GM_CDECL gmItr(gmThread *a_thread, const gmUserObject *a_user, gmTypeIterator &a_it, gmVariable *a_key, gmVariable *a_value)
{
  ...
}

s_simpletype = a_machine->CreateUserType("simple");
a_machine->RegisterLibrary(s_lib, 1);
a_machine->RegisterTypeIterator(s_simpletype, gmItr);


The callback takes the following parameters:
a_thread - The thread used in the callback
a_user - a const pointer to the user object
a_it - a reference to the iterator position
a_key - returns the key (eg: foreach(item and key in object))
a_value - returns the value at the iterator position

The iterator function will continue to process data until the a_it value matches GM_TYPE_ITR_NULL. In the first call to the iterator, the value for a_it will be GM_TYPE_ITR_FIRST - you should treat this as index = 0 and proceed from there.

In order to return data back to GM, two gmVariable* objects are given to you - to return the data associated with the iterator, you populate the a_value parameter and to populate the key, you fill a_key. If your key doesn't have any special data associated with it, I'd return the index as a gmVariable. Before you've finished on this iteration, you need to ensure that you increment the iterator to match the next index position; this will be the next iterator position you receive when the callback finishes.

Imagine the simple vector type:
Code:
struct SimpleVector
{
   SimpleVector() { v[0] = 0; v[1] = 0; v[2] = 0; }
   int v[3];
};


In script, you want to be able to access it using getdot/setdot and getind/setind, we all know how to do that - but what if you want to iterate over it?

Code:
v = createVector();
foreach(item in v)
{
   print(item);
}


Or what if you wanted to iterate over it and see the x, y and z values as keys?

Code:
v = createVector();
foreach(key and item in v)
{
   print(key + ":", item);
}


Would print:
Code:
x:   100
y:   50
z:   92



Some example code for my iterator on the SimpleVector type:

Code:
   void GM_CDECL gmItr(gmThread *a_thread, const gmUserObject *a_user, gmTypeIterator &a_it, gmVariable *a_key, gmVariable *a_value)
   {
      SimpleVector *vector = (SimpleVector*)a_user->m_user;

      int index = a_it;
      if(index == GM_TYPE_ITR_NULL)
      {
         return;
      }
      if(index == GM_TYPE_ITR_FIRST)
      {
         index = 0;
      }
      switch(index)
      {
      case 0:
         a_key->SetString(a_thread->GetMachine()->AllocStringObject("x"));
         break;
      case 1:
         a_key->SetString(a_thread->GetMachine()->AllocStringObject("y"));
         break;
      case 2:
         a_key->SetString(a_thread->GetMachine()->AllocStringObject("z"));
         break;
      };
      if (index >= 0 && index <= 2)
      {
         a_value->SetInt(vector->v[index]);
         a_it = index+1;
         return;
      }
      // Index invalid
      a_it = GM_TYPE_ITR_NULL;
      return;
   }



This is bound to the machine at type registration time:

Code:
   a_machine->RegisterTypeIterator(s_simpletype, gmItr);



And that's it...

The files to change in implementing this are gmMachine.h, gmMachine.cpp and gmThread.cpp. I have left the gmTableObject iterator routines exactly how they were to ensure full backwards compatibility, but it'd be relatively easy to port the table to use exactly the same code. It'd be very easy to add a character iterator to the string class using this code as well.


Attachments:
gmIteratorMod.zip [26.38 KiB]
Downloaded 292 times
Top
 Profile  
Reply with quote  
 Post subject: Re: Type Iterator mod
PostPosted: Wed Apr 08, 2009 6:46 am 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
Nice one downgraded!


Top
 Profile  
Reply with quote  
 Post subject: Re: Type Iterator mod
PostPosted: Wed Jun 24, 2009 1:04 pm 
Offline

Joined: Tue Nov 11, 2008 9:03 am
Posts: 20
Hello,
Could you also provide a patch based on the version your based your mod on ?
Our gmThread is so heavily modified AND not based on the latest GM version, that merging anything into it now is next to utopic.
Thanks very much!


Top
 Profile  
Reply with quote  
 Post subject: Re: Type Iterator mod
PostPosted: Wed Jun 24, 2009 2:11 pm 
Offline

Joined: Tue Nov 11, 2008 9:03 am
Posts: 20
I eventually tracked down all changes related to this mod (they were few luckily) and got it working, thanks!
However I would still strongly suggest to provide patch files instead of raw files when possible.

For those interested here is the iterator implementation for gmArrayLib:
Code:
void GM_CDECL gmUserArray_Iterator(gmThread *a_thread, const gmUserObject *a_user, gmTypeIterator &a_it, gmVariable *a_key, gmVariable *a_value)
{
  GM_ASSERT(a_user->m_userType == GM_ARRAY);
  gmUserArray *array = (gmUserArray *)a_user->m_user;

  int index = a_it;
  if (index == GM_TYPE_ITR_NULL)
  {
    return;
  }
  if (index == GM_TYPE_ITR_FIRST)
  {
    index = 0;
  }

  if ( index >= 0 && index < array->Size() )
  {
    a_key->SetInt( index );
    *a_value = array->GetAtUnsafe( index );
   a_it = index + 1;
   return;
  }

  // Index invalid
  a_it = GM_TYPE_ITR_NULL;
}


Top
 Profile  
Reply with quote  
 Post subject: Re: Type Iterator mod
PostPosted: Wed Jun 24, 2009 5:41 pm 
Offline

Joined: Thu Jan 01, 2004 4:31 pm
Posts: 307
I agree about the patch files. I've been thinking of it for a while now. I'll have a look through al my mods and see what I can come up with


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

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:  
cron
Powered by phpBB® Forum Software © phpBB Group