Articles Archive
Articles Search
Director Wiki
 

Calling behaviors and objects directly

January 14, 2001
by Will Turnage

Dear Multimedia Handyman:

I've been learning how do object-oriented programming in Director. I believe that I have a firm grasp on everything except making calls between objects.

What are the different ways that I can make calls from a behavior to a behavior, from a behavior to a child instance, from a child instance to a child instance, and from a child instance to a behavior?

Thanks, John

John:

The first thing to understand when making calls between objects is that as far as Lingo is concerned, an object is an object, whether it's a child object or a behavior. And the first step to calling an object directly is to retrieve the reference of that object. A reference is essentially Director's way of keeping track where all of its data and handlers are stored.

If you're using custom parent scripts, then finding its reference is pretty easy. For example, if you create your objects as global variables, then they can be accessed from anywhere.

gPerson = new (script "personal data script")
put gPerson
-- <offspring "personal data script" 2 a7e4040>
showglobals
-- Global Variables -- 
gPerson = <offspring "personal data script" 1 a7e4040>
version = "7.0.2"  

In this case, the reference to your variable is simply gPerson. If gPerson had an ancestor that you wanted to access directly you could use gPerson.ancestor as your reference.

The big question now is: how do I find the reference of a behavior? Well, behaviors are objects too, but their references are stored a little differently than globals. There are two main ways to retrieve references to behaviors.

The first way is to use the scriptInstanceList of a sprite. This value, which is only available when the Director movie is running, is a list of all the instances of behaviors attached to any given sprite. For instance:

put the scriptInstanceList of sprite 7
-- []

Now that you know about a list containing the reference to your behavior, you can store that reference in your own variable, in this case:

tempRef =  sprite(7).scriptInstance[1]  

The final way to get a reference to a behavior (or any object, for that matter) is from the object itself. When you look at any handler within an object or behavior, you will notice that the first argument listed after the handler name is the word me.In Lingo, me is a reference to the behavior that contains the handler, and it can be returned as the value from a function. For example, you could attach a behavior to sprite 7 that contains this handler:

on returnMyInstance me
   return me
end

and then you could use this Lingo from anywhere else in Director to find the reference of that behavior and store it in a variable.

tempBehaviorReference = sendSprite(7, #returnMyInstance)  

Once you have found the reference to whatever object you want, then you can call any handler or property in that object directly.

Say you've created an object that tracks a person's age and weight. Naturally, you'd want the object to have a handler inside it that allowed you to set new values for age and weight.

on setAgeAndWeight me, firstNum, secondNum
  pAge = firstNum pWeight = secondNum
end

If you created this object as a global variable, you can call the setAgeAndWeight handler from anywhere. Director gives you three basic ways to call the handler directly.

call(#setAgeAndWeight, gPerson, 42, 210) 
setAgeAndWeight(gPerson, 42, 210) 
gPerson.setAgeAndWeight(42, 210) 

The first way uses the Lingo method call. When you use call, the first parameter you enter is the handler name, the second parameter is the object, and the rest of the parameters are the arguments required by your handler.

The second way listed calls the handler by name. If you script in this style, it is very important that the first argument listed in your handler is the object that contains the handler. If it is not the first parameter, then Director could either give you an error or call the wrong object. This way of calling a handler within an object is used quite frequently with third party Xtras.

The third way of calling the script is essentially the same as the second way, but using dot syntax instead. Some people prefer this method because the object gets listed first, which makes your code a bit easier to read.

At first, these three ways of calling handlers directly might all seem the same, but there is one key difference. When you use the second and third ways of calling objects, you are limited to calling only one object directly. However, if you use the call function, you can specify either a a single object or a list of objects. If you use a list of objects, then the function will call the handler in each and every object contained in your list. For example:

global gPersonOne, gPersonTwo, gPersonThree
on mouseUp me
  
objList = [gPersonOne, gPersonTwo, gPersonThree]
  call(#setAgeAndWeight, objList, 42, 210)
end

In this example, the handler setAgeAndWeight will be called on all three objects. So if your project has multiple objects, or different groups of objects, then you can put their references into custom lists and call them all at once using the call function.

The previous example uised a global variable, but it could have just as easily have used a behavior. The only difference is that you would have started by finding the reference to the behavior:

tempRef = sprite(7).scriptInstanceList[1]         

and then you could use any one of the three ways to call the behavior directly.

call(#setAgeAndWeight, tempRef, 42, 210)
setAgeAndWeight(tempRef, 42, 210)
tempRef.setAgeAndWeight(42, 210) 

A sample Director 7 movie is available for download in Mac or Windows format.

Will Turnage is a multimedia programmer based in New York City. In addition to his weekly role as Director Online's Multimedia Handyman, he is also the Technology Director for Sony Music's Client Side Technologies Group. You can read more about his work at http://will.turnage.com/.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.