6.7 Animation Controller
6.7.4 Execution Scheduler
The execution scheduler triggers events at a certain time, as specified in the resulting network trace of a scenario, and controls the playback of a scenario. Its input is the compressed multi-dimensional text data that details each network event as shown in Figure 77 and in more detail in Figure 81. The structure of the execution scheduler is similar to previous schedulers written in ActionScript 2.0 and ActionScript 3.0.
Figure 81: Operations of the execution scheduler developed in Second Life
Figure 81, step 1
The scheduler receives a string which is the compressed scenario trace providing information on every network event in the scenario (see section 6.7.3).
Figure 81, step 2
The scheduler then splits the string into a list of lists; as such, the compressed scenario trace is a multidimensional list. The split is performed by generating a list of colon delimited strings. These
130
strings are further split to provide a list that relates to an event in the simulation. The functions that perform these splits are shown in Figure 82.
//splits the new events into a list from the raw string from output = ls list addNewEvents(string moreEvents){
return llParseString2List(moreEvents,[":"],[""]); }
list convertStrEventToList(string aevent){ return llParseString2List(aevent,[","],[]); }
Figure 82: A sample of LSL code used to split the compressed NAM results into a manageable format
Once the list returned by the method “convertStrEventToList”, the scheduler can extract key bits of information from the protocol such as the time of an event and the source node of a message. These pieces of information are accessed in accordance with good coding practices as shown in Figure 83.
float getTimeFromEvent(list anEvent){ return llList2Float(anEvent,timeIndex); }
integer getSourceNodeFromEvent(list anEvent){
return llList2Integer( anEvent,sourceNodeIndex); }
Figure 83: A sample of LSL code used to index into an event using the constants specified in Figure 78
Figure 81, step 3
The scheduler has a constant tick rate which allows the subdivision of the simulation into periodic events representing a slice of simulation time. Using a steady tick rate and a monotonic counter, the counter can be converted to simulation time by dividing by a constant to calculate the simulation time (Figure 84 line 7). 1. integer ticks = 0; 2. float simulationTime = 0; 3. integer divisor = 1800; 4. list eventList = []; 5. timer(){ 6. ticks++; 7. simulationTime=(float)((float)ticks/(float)divisor); 8. executeAnyLessThanThis(simulationTime); 9. }
Figure 84: LSL example code from the Execution Scheduler component in WiFiSL
The buffer eventList contains events to be executed on the next tick of simulation time. While executing, the events list is scanned progressively, halting once a value is encountered larger than the next simulation tick time (maxTime). Events that are to be executed are then executed using the Event Handler method. The executed events are deleted from the events list
131 1. executeAnyLessThanThis(float maxTime){
2. for(integer ptr=0; ptr<llGetListLength(eventList); ptr++){
3. list anEvent = convertStrEventToList(llList2String(eventList, ptr));
4. //if we go over the max time, everything before it will be deleted 5. //As it should be already handled below
6. if(ptr!=0 && getTimeFromEvent(anEvent)>maxTime){ 7. eventList = llDeleteSubList(eventList, 0, ptr-1); 8. return; 9. } 10. … 11. else{ 12. handleEvent(anEvent); 13. } 14. }
Figure 85: Sample code from the Execution Scheduler showing the selection of events to execute for a given maximum simulation time
Figure 81, step 4
The handleEvent method (Figure 86, line 2) extracts from an event its type, source ID (from ns-2) and its destination ID (ns-2). This method constructs a protocol message that instructs a particular listening component to animate an event. The particular node is indicated through the use of the Second Life key. There will always be a valid source address, the translation occurs in line 7. Not all network events have a valid destination address when broadcasting a destination address of -1 is used. As such, line 8 checks that there is a valid address before attempting the translation from ns-2 ID to a Second Life key. Once the animation message has been constructed, it is sent over the island-wide animation chat communication channel. All nodes listen on the animation channel and if they detect their Second Life key, as the originating key then the node initiates the animation of that packet.
1. //called for immediate display/action 2. handleEvent(list aevent){
3. //also needs a translation from node id to SL key 4. integer pktType = getPacketTypeFromEvent(aevent); 5. string msg="";
6. if(pktType != MOV){
a. msg = (string)pktType + ":" + llList2String(slID, getSourceNodeFromEvent(aevent))+":";
7. //if the destination address is broadcast (i.e. -1) 8. if(getDestinationNodeFromEvent(aevent)!=-1){
9. msg += llList2String(slID,getDestnNodeFromEvent(aevent)); 10. else msg = msg + "-1";
11. llRegionSay(animationChannel, msg);
Figure 86: Sample code from the Execution Scheduler showing how events are transmitted to listening networking components on the island
The design choice for using llRegionSay for instructing a node to animate an event rather than the scheduler animating the event is due to the restraints in Second Life. Initially, to avoid any latency on the island and the simulator, networking components were linked together and communicated using
llLinkedMessage. The limitation was that components could not be more than 5 metres apart which would limit the range of scenario constructions available. Another option was to have the Execution Scheduler rez the signal at the networking component’s position. There are limits on the distance at which one object can rez another object; currently set to a 10 metre radius, which again restricts the range of simulation scenarios available and does not make use of the immersive environment of the
132
whole island. As such, by using the llRegionSay communication method and allowing each node to render the animation, island-wide simulations are possible.
Figure 81, step 5
The animation message is received by all the nodes on the island listening on the pre-calculated channel. Each node will receive the message and check if their Second Life key is a designated transmitter. If so, then the node will check the destination key. If a negative number is specified, the node will animate the signal in a broadcast manner. If a Second Life key is present, using a Second Life API call it will target a specific networking component using its x, y and z coordinates. The type of signal varies and a colour coding system is used to facilitate the recognition of signals, thus the signal type is checked before animation. More detail on the animation of broadcast and directional messaging can be found in section 6.5.
Due to the limitations imposed in LSL, the Execution Scheduler cannot maintain a full listing of the results of a simulation despite the large compression provided. Due to this space restriction, the scheduler will send a message requesting more simulation results. The extra results, when returned, are appended to the current list of results and this process continues until no more results are available. The user is capable of altering the pace of the animation by using the “Animation Board” that is available within the avatar’s inventory alongside the All Seeing Orb and the Node.