Object Groups and Sets - KidneyThief/TinScript1.0 GitHub Wiki
More of a a support feature of the environment, and not specifically a syntax element of the language, TinScript includes two registered classes conveniently manage and filter collections of objects. In the same way that Windows organizes your data into folders, and files within each folder, You can use the following two classes to manage a hierarchy of objects:
- An object set is created just like any other object, by using the 'create' keyword:
- object my_set = create CObjectSet("MySet");
- It's a collection, so it provides an interface to add and remove objects
-
::AddObject(<objectid>)
- Adds an object to this set.
-
::RemoveObject(<objectid>)
- Removes an object from this set.
-
::AddObject(<objectid>)
- There are two methods used to determine the contents of a set:
-
::Contains(<objectid>)
- Returns true, if the objectID is a member of this set
-
::ListObjects();
- Mostly for debugging, this prints the hierarchy of objects.
- It calls PrintObject() for each object, listing the ID, the name, and the namespace hierarchy.
- For any object in the set that itself is a CObjectSet, it will call ListObjects() on that object as well, resulting in a complete display of the entire tree.
-
::Contains(<objectid>)
- There are also two methods called, when an object is added or removed from a set. These calls happen automatically, just like ::OnCreate() and ::OnDestroy():
-
::OnAdd(<objectid>)
- This CObjectSet method is automatically called when an object is added to this set.
-
::OnRemove(<objectid>)
- Likewise, this method is automatically called when an object is removed from this set.
-
::OnAdd(<objectid>)
- One important point about sets - the methods described below will iterate through the objects in a set, in the same order in which they were added.
- There are two ways of iterating through a CObjectSet
-
::First()
- Returns the first object added to the set (can be assigned to a variable of type object).
-
::Next()
- Once First() has been called, an internal iterator is initialized, and Next() can be continuously called until it has iterated through the entire contents of the set.
- An important feature of this approach - if an object in the set is removed (deleted, etc...) while iterating through the set, calling Next() will always return the "correct" next object.
- Because the iterator is internal, this approach doesn't support multiple loops iterating through the set simultaneously, as calls to Next() from each loop would interfere with each other.
-
::First()
- The second approach for iterating through a CObjectSet does so by index:
-
::Used()
- This method will return the number of objects contained within the set.
-
::GetObjectByIndex(<index>)
- Iterating from index '0' to an index one less than the number returned by Used() will also allow you to access every object in the set.
-
::Used()
A CObjectGroup operates the same way as a CObjectSet - all of the above methods and usage patterns are supported in the same way. The only difference is, membership in a CObjectGroup implies ownership. An object is only allowed to belong to a single CObjectGroup, whereas, an object can belong to as many CObjectSets as you'd like.
-
::AddObject(<objectid>)
- This method does the same for a CObjectGroup as for a CObjectSet, with one exception - if the object currently belongs to a CObjectGroup, it is automatically removed from that group before being added to this one.
-
::GetGroupID()
- This is a method available to all registered or created objects, just like ::GetObjectID(). It returns the CObjectGroup object that currently contains (owns) this object.
- We'll define two groups, each with an "OnAdd" and an "OnRemove" method
- // TestGroupA methods
void TestGroupA::OnAdd(object obj_id)
{
Print("A-group added: ", obj_id.GetObjectName());
}
void TestGroupA::OnRemove(object obj_id)
{
Print("A-group removed: ", obj_id.GetObjectName());
}
// TestGroupB methods
void TestGroupB::OnAdd(object obj_id)
{
Print("B-group welcomes: ", obj_id.GetObjectName());
}
void TestGroupB::OnRemove(object obj_id)
{
Print("B-group byebye: ", obj_id.GetObjectName());
}
- // TestGroupA methods
- Now we'll create one of each type of group
- object groupA = create CObjectGroup("TestGroupA");
object groupB = create CObjectGroup("TestGroupB");
- object groupA = create CObjectGroup("TestGroupA");
- An approach to automatically filtering objects, is to add the to their group in an "OnCreate" method:
- void GroupAChild::OnCreate()
{
groupA.AddObject(self);
}
void GroupBChild::OnCreate()
{
groupB.AddObject(self);
}
- void GroupAChild::OnCreate()
- Create an instance of each type of 'child', and watch to see them added to their respective parent groups.
-
object childA = create CScriptObject("GroupAChild");
- output: A-group added: GroupAChild
-
object childB = create CScriptObject("GroupBChild");
- output: B-group welcomes: GroupBChild
-
object childA = create CScriptObject("GroupAChild");
- List the objects in each group:
-
groupA.ListObjects();
- output: [x] GroupAChild: GroupAChild-->[CScriptObject]
-
groupB.ListObjects();
- output: [x] GroupBChild: GroupBChild-->[CScriptObject]
-
groupA.ListObjects();
- Add the GroupAChild to groupB, and watch the ownership change:
-
groupB.AddObject(childA);
- output: A-group removed: GroupAChild
- output: B-group welcomes: GroupAChild
-
groupA.ListObjects();
- no output: no objects should be listed, since childA no longer "belongs" to groupA
-
groupB.ListObjects();
- output: [x] GroupBChild: GroupBChild-->[CScriptObject]
- output: [x] GroupAChild: GroupAChild-->[CScriptObject]
- note the order listed is the order in which the objects were added to groupB.
-
groupB.AddObject(childA);
- One final test - lets add groupB as a child to groupA
-
groupA.AddObject(groupB);
- output: A-group added: TestGroupB
-
groupA.ListObjects();
- output: [x] TestGroupB: TestGroupB-->[CObjectGroup]-->[CObjectSet]
- output: [x] GroupBChild: GroupBChild-->[CScriptObject]
- output: [x] GroupAChild: GroupAChild-->[CScriptObject]
-
groupA.AddObject(groupB);