# Sending Messages to Sequences and Collections

After a task creates a Juggler object, it can send messages to the object. This section describes the messages that sequences and collections accept and also describes the actions of the methods in response to the messages.

The function for a method can be different for different types of objects. Therefore, the results of identical messages sent to different objects can vary.

## Calling Methods Directly

Methods are defined within an object with a list of pointers to functions. A task can call any of these methods directly using the pointer to the method's function that is in the object data structure. For example, `*obj->Class->Add` calls an object's Add method.

## Message Macros

Many of the methods available to Juggler objects can be called through macros provided by the Music library. To make your code more legible, you should use macros whenever possible. For example, the macro `StopObject()` calls the method `*obj->Class->Stop`. See Method Macros for a list of macros.

## Messages for Sequences

Although a sequence accepts messages for all the common Juggler methods, not all methods have meaningful results for a sequence. For example, a sequence accepts an Add message to add an object to an object list, but the message does not do anything meaningful because the sequence has no object list. The following sections describe the methods that give meaningful results for a sequence.

### Alloc

The Alloc method allocates memory for a sequence's event list. The Alloc method is called using this macro:

  `int32 AllocObject( CObject *obj, int32 Num )`

The call accepts two arguments: `*obj`, a pointer to the sequence for which memory should be allocated; and `Num`, an integer that specifies the number of events in the event list.

When it executes, the call uses the event size stored in the sequence to allocate an appropriate amount of RAM for the event list. It stores a pointer to the allocated RAM into the object variable `*obj->seq_Events`. `AllocObject()` returns 0 if successful or a negative value (an error code) if unsuccessful.

Aa task does not have to use this method to allocate memory for an event list. The method is provided as a convenience. A task can use its own allocation techniques.

### Free

The Free method frees memory previously allocated for a sequence's event list by the sequence's Alloc method. The Free method is called by this macro:

  `int32 FreeObject( CObject *obj )`

The call accepts one argument: `*obj`, a pointer to a sequence.

When it executes, the call frees any memory previously allocated for the sequence's event list. If successful, `FreeObject()` returns 0. If unsuccessful, it returns a negative value (an error code).

If a task allocates memory for an event list using its own techniques, the memory should be freed using its own techniques.

### SetInfo

The SetInfo method sets a sequence's variables with values provided by a tag argument list. The SetInfo method is called by the following macro:

  `int32 SetObjectInfo( CObject *obj, TagArg *tags )`

The call accepts two arguments: `*obj`, a pointer to the object to which the tag argument values should be applied; and `*tags`, a pointer to the tag argument list. When executed, the call sends a SetInfo message to the specified object. The object reads the values in the tag argument list and applies them to the appropriate object variables.

`SetObjectInfo()` returns 0 if successful, or a negative value (an error code) if unsuccessful.

### GetInfo

The GetInfo method returns a sequence's variable values by writing them to a provided tag argument list. It's called by this macro:

  `int32 GetObjectInfo( CObject *obj, TagArg *tags )`

The call accepts two arguments: `*obj`, a pointer to the object for which values should be retrieved; and `*tags`, a pointer to a tag argument list. The call sends a GetInfo message to the specified object. The object writes its current variable values into the tag argument list.

`GetObjectInfo()` returns 0 if successful, and a negative value (an error code) if unsuccessful.

### Start

The Start method makes a sequence active so that it can be played by the Juggler when the Juggler is bumped (See Bumping the Juggler). The method is called by the following macro:

  `int32 StartObject( CObject *obj, uint32 Time, int32 NumReps, CObject *Parent )`

The call accepts four arguments: `*obj`, a pointer to the sequence to be started; `Time`, an absolute time in ticks when the sequence should be started; `NumReps`, the number of times the sequence should be repeated in playback; and `*Parent`, a pointer to the parent of the sequence.

The `*Parent` pointer is only used when a sequence is part of a collection. A task using this call directly should set `*Parent` to NULL. The `NumReps` value only sets the number of playback repetitions for a sequence if the sequence is not part of a collection. If it is part of a collection, the number of repetitions stored in the sequence's placeholder overrides this value.

When `StartObject()` executes, the call stores the `Time` and `NumReps` values in the appropriate sequence variables. The Juggler uses the start time to determine the absolute event times (See Absolute and Relative Event Times). The Juggler uses the `NumReps` value to determine how many times to play the sequence.

`StartObject()` returns 0 if successful, and a negative value (an error code) if unsuccessful.

### Stop

The Stop method makes a sequence inactive (it is no longer be played by the Juggler). The Stop method is called by this macro:

  `int32 StopObject( CObject *obj, uint32 Time )`

The call accepts two arguments: `*obj`, a pointer to the sequence to be stopped; and `Time`, an absolute time in ticks that reports when the object was stopped.

When executed, the call makes the sequence inactive so that none of its events are played by the Juggler. The reported stop time is passed by the stopped object to any existing parent objects. `StopObject()` returns 0 if successful, and a negative value (an error code) if unsuccessful.

Note: A task should be careful when stopping a sequence contained within a collection. The sequence may stop for a while, but if it is repeated by the collection or called by another placeholder, it may start again. In other words, stopping a sequence within a collection may have unpredictable results.

### Print

The Print method prints debugging information about a sequence. The Print method is called by this macro:

  `int32 PrintObject( CObject *obj )`

The call accepts one argument: `*obj`, a pointer to the sequence for which information should be printed.

When executed, the call prints debugging information about the specified sequence, including a pointer to the sequence. `PrintObject()` returns 0 if successful, and a negative value (an error code) if unsuccessful.

## Messages for Collections

A collection accepts all the common jugglee class methods, but only some of them have meaningful results for a collection. The following sections describe the methods that have meaningful results for a collection.

### Alloc and Free

These methods have no meaningful results for a collection.

### SetInfo and GetInfo

These methods, called by the macros `SetObjectInfo()` and `GetObjectInfo()`, perform the same actions as they do for a sequence.

### Add

The Add method adds a Juggler object to a collection's object list. There is no macro for this method. The Add method is called directly, as follows:

  `*obj->Class->Add( Collection *Self, Jugglee *Child, int32 NumRepeats)`

See Adding Objects to the Collection for more information on the Add method.

### GetNthFrom

The GetNthFrom method looks at a specified position in a collections's object list and retrieves a pointer to the Juggler object. The GetNthFrom method is called by the following macro:

  `int32 GetNthFromObject( CObject *obj, int32 N, (void**) NthThing )`

See Examining a Collection's Object List for more information on the GetNthFrom method.

### RemoveNthFrom

The RemoveNthFrom method removes the object from a specified location within a collection object list. The RemoveNthFrom method is called by this macro:

  `int32 RemoveNthFromObject( CObject *obj, int32 N )`

See Removing Objects From a Collection for more information.

### Start

The Start method, called by the macro `StartObject()`, works the same for a collection as it does for a sequence, that is, it makes a collection active so that it can be played by the Juggler.

When a collection is started, all of its component objects are started with it, and play back in parallel (not in sequence, as the events within a sequence play).

A collection, like a sequence, stores `Time` and `NumReps` values in the appropriate variables so the Juggler can use those values to determine absolute event times and how many times to repeat the collection. During repeats, all of the collection's constituent objects are replayed.

### Stop

The Stop method, called by the macro `StopObject()`, works the same for a collection as it does for a sequence; that is, the collection is made inactive so that it is no longer be played by the Juggler. When a task stops a collection, the collection sends Stop messages to all of its constituent objects so that they stop as well.

Note: A task should not stop a collection that is a constituent of a higher collection, because the results are unpredictable. The higher collection may restart the collection that was stopped.

### Print

This method, called by the macro `PrintObject()`, prints debugging information as it does for a sequence. It also prints a list of the objects contained in the collection's object list.