Game Development Community

Cancelling schedules

by Ian Omroth Hardingham · in Torque Game Engine · 11/21/2002 (10:46 pm) · 14 replies

Hey,

during debugging, it would be a great help if, when reloading my script, I could cancel all currently running schedule calls on my script. Is this possible?

Ian

#1
11/22/2002 (11:48 am)
I'm not sure how you'd kill them all, but the way to cancel a schedule that I know of is to do something like the following:

%theschedule = schedule(blah);

cancel(%theschedule);

and I think you can do

%theschedule.delete();
#2
06/07/2006 (10:23 pm)
I figured it'd be better to necro up this old thread than to start a new one.

Does anyone know if a way to do this has been found in the last four years? The HEAVILY scripted demo I've put together uses a lot of schedules. Unfortunately I didn't think about someone quitting in the middle of the demo and restarting it, thus causing it run improperly as the still scheduled functions start running at the wrong times.

Just thought I'd ask and see if there were some kind of blanket cancel now before I jump in and handle them all individually.
#3
06/07/2006 (10:32 pm)
Well I wrote something just for this. It requires the use of the script array resource.
I just wrote it a few days ago specific for my needs. But it can probably work for you too.

it's very simple. instead of making a call to schedule, you do a call to advschedule instead.
It stores a list of all schedules and variables in an array. you can stop them all, and restart them whenever you like.


example

advschedule(1000,0,echo,"Echo now");



Let me know if you need further explanation.





//create the schedule array
$advScheduleQueue = new Array();


function advSchedule(%time,%object,%function,%arg1,%arg2,%arg3,%arg4,%arg5,%arg6,%arg7){

   %schedule = schedule(%time,%object,%function,%arg1,%arg2,%arg3,%arg4,%arg5);
   %arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
  
   //lets do a cleanup before adding anything
   AdvScheduleCleanup();

   //Add the schedule to the advschedule list
   $advScheduleQueue.add(%schedule,%arguments);
}


function AdvScheduleCleanup(){

%temp = new Array();

   for (%c=0; %c<$advScheduleQueue.count(); %c++){
      
      %schedule = $advScheduleQueue.getKey(%c);
   
      %Rtime = getEventTimeLeft(%schedule);
      if (%Rtime){
         %value = $advScheduleQueue.getValue(%c);
          %temp.add(%id,%value);
      }
   }
$advScheduleQueue.empty();
$advScheduleQueue.duplicate(%temp);
%temp.delete();

}

function CancelAdvSchedules(){
   
   for (%c=0; %c<$advScheduleQueue.count(); %c++){
      
      %str = $advScheduleQueue.getValue(%c);
      
      %id = $advScheduleQueue.getKey(%c);
      %Rtime = getEventTimeLeft(%id);
      %str= setRecord(%str,0,%Rtime);
      $advScheduleQueue.setValue(%str,%c);
            
      cancel(%id);
   }
}


function RestartAdvSchedules(){
   
   //Copy over the schedule queue, then empty it
   %temp = new Array();
   %temp.duplicate($advScheduleQueue);

   $advScheduleQueue.empty();
   
   for (%c=0; %c<%temp.count(); %c++){
      %arguments = %temp.getValue(%c);
      %time = getRecord(%arguments,0);
      %object = getRecord(%arguments,1);
      %function = getRecord(%arguments,2);
      %arg1 = getRecord(%arguments,3);
      %arg2 = getRecord(%arguments,4);
      %arg3 = getRecord(%arguments,5);
      %arg4 = getRecord(%arguments,6);
      %arg5 = getRecord(%arguments,7);
      %arg6 = getRecord(%arguments,8);
      %arg7 = getRecord(%arguments,9);
      advSchedule(%time,%object,%function,%arg1,%arg2,%arg3,%arg4,%arg5,%arg6,%arg7);
   }
   
   //delete temp array
   %temp.delete();
}
#4
06/07/2006 (10:37 pm)
Surely just keep a list of shedule ids used and cancel them all once you clean up?

EDIT: Doh, new posts showed up as I was typing, ignore me by all means ;p

~neo
#5
06/07/2006 (10:43 pm)
Awesome! Thanks a lot Ramen, that's exactly what I need. I'll let you know if I have any problems.

@Neo
Heh, you posted as I was typing a response as well. That's what I would have done if I had forseen this issue like I should have, but there's just so many of them all over the place at this point that this will be far easier.
#6
06/08/2006 (9:30 am)
Thanks again Ramen, that did the trick. I just had to modify it slightly so the schedule could work for both global and namespace, as well as some tinkering with handling the arguments. alxPlay apparently doesn't like extra null arguments being passed to it. Other than that everything worked like a charm and saved some serious mundane and potentially error causing work.
#7
06/08/2006 (11:06 am)
Though it's not relevant for the advanced needs here of stopping and starting global schedules in game, using method schedules when possible is much safer. Schedules called as methods of an object are automatically cancelled when the parent object is deleted (and presumably when the mission is ended).
#8
06/08/2006 (5:21 pm)
@Scott

I could probably add some extra checking to determing how many arguments its needing to pass, but i just wrote that script in a hurry. if you modified that part to have it automatically determine the needed number of arguments, i could use the update, if not. i may get around to it myself sometime
#9
06/08/2006 (6:39 pm)
@Ramen

Apparently my post didn't go through so I'll try again.

The modifications I made are rather quick and dirty as well, just some if/else's based on a %numarg argument I added to advSchedule. There's also a bool I added for global/namespace scheduling.

function advSchedule(%time,%object,%function, %global, %numarg, %arg1,%arg2,%arg3,%arg4,%arg5,%arg6,%arg7)
{
	if(%global)
	{
		if(%numarg == 0)
		{
			%schedule = schedule(%time,%object, %function);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
		else if(%numarg == 1)
		{
			%schedule = schedule(%time,%object, %function, %arg1);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
		else if(%numarg == 2)
		{
			%schedule = schedule(%time,%object, %function, %arg1, %arg2);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
		else if(%numarg == 3)
		{
			%schedule = schedule(%time,%object, %function, %arg1, %arg2, %arg3);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
	}
	else
	{
		if(%numarg == 0)
		{
			%schedule = %object.schedule(%time, %function);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
		else if(%numarg == 1)
		{
			%schedule = %object.schedule(%time, %function, %arg1);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
		else if(%numarg == 2)
		{
			%schedule = %object.schedule(%time, %function, %arg1, %arg2);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
		else if(%numarg == 3)
		{
			%schedule = %object.schedule(%time, %function, %arg1, %arg2, %arg3);
			%arguments = %time @ "\n" @ %object @ "\n" @ %function @ "\n" @ %arg1 @ "\n" @ %arg2 @ "\n" @ %arg3 @ "\n" @ %arg4 @ "\n" @ %arg5  @ "\n" @ %arg6  @ "\n" @ %arg7;
			
			//lets do a cleanup before adding anything
			AdvScheduleCleanup();
			
			//Add the schedule to the advschedule list
			$advScheduleQueue.add(%schedule,%arguments);
		}
	}  
}
#10
06/08/2006 (7:13 pm)
I didn't really test this code.. but perhaps something like this would be better?
It takes up less space. Might take longer because it does a string compare.. but it's alot easier to read.
For this code i didn't include any mentiong of your %global variable. But i'm sure you could figure it out


function advSchedule(%time,%object,%function, %arg1,%arg2,%arg3,%arg4,%arg5,%arg6,%arg7)
{
	%arguments = %time @ "\n" @ %object @ "\n" @ %function

	if (%arg1 !$= "")
		%arguments = %arguments @ "\n" @%arg1;
	if (%arg2 !$= "")
		%arguments = %arguments @ "\n" @%arg2;
	if (%arg3 !$= "")
		%arguments = %arguments @ "\n" @%arg3;
	if (%arg4 !$= "")
		%arguments = %arguments @ "\n" @%arg4;
	if (%arg5 !$= "")
		%arguments = %arguments @ "\n" @%arg5;
	if (%arg6 !$= "")
		%arguments = %arguments @ "\n" @%arg6;
	if (%arg7 !$= "")
		%arguments = %arguments @ "\n" @%arg7;


	//lets do a cleanup before adding anything
	AdvScheduleCleanup();
			
	//Add the schedule to the advschedule list
	$advScheduleQueue.add(%schedule,%arguments);

}


I did : if (%arg6 !$= "")

Cause i couldn't figure out how to tell if a variable == NULL
An issue i see with this is if say arg1 is null and arg2 isnt, then it will write Arg2 down as arg1. So i guess you would have to ensure that you don't putl any nulls anywhere in your arguments.

Perahaps some more logic could be added to check for such things.
#11
09/20/2006 (1:42 pm)
Hi I would like to set up a cancel function in this:

function clientCmdPushInventory(%player)
{
   inventoryHUD.setVisible(true); 
   schedule(2000,0,"popInventoryHUD");
}

function popInventoryHUD()
{
   inventoryHUD.setVisible(false);
}

Since this is pulled everytime I scroll my mouse I need to cancel the scheduled event and then reschedule it. I have tried the cancel and it makes no difference. Has anyone gotten something simple to work?
#12
09/20/2006 (1:55 pm)
This was mentioned in another post a few hours ago.

function clientCmdPushInventory ( %player )
{   
    inventoryHUD.setVisible ( true );    
    $schedule = schedule ( 2000, 0, "popInventoryHUD" );
}

function popInventoryHUD ()
{   
    inventoryHUD.setVisible ( false );
    cancel ( $schedule );
}
#13
09/20/2006 (2:16 pm)
Well thank you very much. That is certainly a twist on what I had.
#14
11/15/2008 (3:48 pm)
Note for future archaelogists,
if you're using a codebase without getEventTimeLeft(), (eg TGE 1.3.5),
here's an implementation.

SimBase.cc
right after the consolefunction isEventPending():
ConsoleFunction(getEventTimeLeft, S32, 2, 2, "remainingTime(%scheduleId);")
{
   argc;
   return Sim::getEventTimeLeft(dAtoi(argv[1]));
}