Bridge Commander Central
BC Forums => BC Scripting => Topic started by: Bat66wat6 on August 01, 2013, 08:22:00 PM
-
Title is almost self-explanatory and again i'm sure this has been brought up infinity times before.
Possible to create a delayed call to a function with pre-defined arguments?
The question to answer is, how to call a function like:
def MyFunction(pShip, flag=0, pObjectName):
print pShip
print flag
print pObjectNamewith pre-determined arguments after a set amount of time?
I have been searching the BC API for hours and am yet to find anything promising.
I would really love not to have to develop a butt ugly hack workaround involving globals and middle man functions :(
When replying, please remember I am noob at this stuff.
Only ever created my timers using MissionLib.CreateTimer .
- - - - -
Also currently searching BCS-TNG but the search feature is terribad with CAPTCHA for every search.
Someone been terrorizing the domain with bots? :lostit:
-
Before I say anything what exactly are you trying to achieve?
Someone been terrorizing the domain with bots?
Not recently. I just don't want bots overloading the database.
-
I'm trying to achieve a delay before the execution of code.
An event happens (a function fires ... in this case subsystemdisabled but it doesn't matter).
..... delay .....
Function to handle that event is called.
If the function is: MyFunction(arg1, arg2, arg3) then in this case I may want to call it as:
MyFunction(pShip, 0, pDisabledObjectName)
...
except after a delay of course.
The delay can't hang up the entire script or the game.
Python
import time
time.sleep()
Pauses the entire game.
-
I'm trying to achieve a delay before the execution of code.
An event happens (a function fires ... in this case subsystemdisabled but it doesn't matter).
..... delay .....
Function to handle that event is called.
If the function is: MyFunction(arg1, arg2, arg3) then in this case I may want to call it as:
MyFunction(pShip, 0, pDisabledObjectName)
...
except after a delay of course.
The delay can't hang up the entire script or the game.
Python
import time
time.sleep()
Pauses the entire game.
if im reading this right you want to essentially "pause" the games functions after something happens like and RPG does with commands?
like if you fire off a torpedo, then the game pauses allowing you to make choices and decisions based on a set limit before everything restarts again real time?
(im following this and am interested :P)
-
if im reading this right you want to essentially "pause" the games functions after something happens like and RPG does with commands?
like if you fire off a torpedo, then the game pauses allowing you to make choices and decisions based on a set limit before everything restarts again real time?
(im following this and am interested :P)
Wrong :nono:
The game should not pause. The script should not pause.
The game must continue during the delay. The script must continue reacting to events and doing everything else it needs to during the delay.
Ergo, that's the reason for me mentioning MissionLib.CreateTimer(). It permits for a function to be called after a set delay (current time + delay) but does not pause the entire game or execution of the script in which it is called.
The problem with MissionLib.CreateTimer (and all timers it seems) is that they do not permit any arguments other than (pObect, pEvent)
To my knowledge all functions in BC that are triggered by a Totally Games timer have the format:
def Function(pObject, pEvent):
#code here
The question presented in this thread is whether it is possible to call a function such as:
def MyFunction(customArg1, customArg2, customArg3):
# use my arguments hereafter a set amount of time with its arguments.
I hope I have been clear enough.
-
How about specifying a custom event -type/class with the needed variables?
That way you could call your function via the normal timer.
(But I have no Idea how that would work in detail - my own timer dependent scripts all resulted in an absolute mess)
-
How about specifying a custom event -type/class with the needed variables?
That way you could call your function via the normal timer.
(But I have no Idea how that would work in detail - my own timer dependent scripts all resulted in an absolute mess)
I have done just that. A class that provides add / remove and storage of arguments for each call.
It's gotten quite messy but that's because i'm storing alot in the global:
key: [shipID] values: [expiredFlag, eventID, timerID, funcArgs, callSelector]
(funcArgs is a list)
and providing methods to 'cancel' the call (function checks a global and suicides if a flag isn't set), get arguments.
No doubt the way I'm doing things is not as clean as it could be but whatever, it's a hacked workaround.
I will post the code if it gets clean enough for other people to read and if somebody doesn't come up with a 'legit' method of doing this in BC.
:\
-
That's pretty easy stuff :)
To oversimplify the implementation, class implementation with an internal time slice process.
I found a sample I had on my repository:
# Imports
import App
# Constants
TimerNotRunning = 0
TimerStarted = 1
TimerRunning = 2
TimerStopped = 3
# Object with an internal timer
class TimedObject:
# Constructor, define as many parameters as you'd want
def __init__(self, parameter1, parameter2, parameter3, delay):
self.status = TimerNotRunning
self.pTimer = None
self.param1 = parameter1
self.param2 = parameter2
self.param3 = parameter3
self.delay = delay
def StartTimer(self):
if not self.pTimer:
# Start tme slice process
self.pTimer = App.PythonMethodProcess()
self.pTimer.SetInstance(self)
self.pTimer.SetFunction("TimerSliceUpdate")
self.pTimer.SetPriority(App.TimeSliceProcess.LOW)
self.pTimer.SetDelay(self.delay)
self.status = TimerStarted
def TimerSliceUpdate(self, fTime):
# Check if time slice process is running
if (self.status == TimerRunning):
# Kill instance
self.status = TimerStopped
global activeTimers
activeTimers.remove(self)
# Set status to running
elif self.status == TimerStarted:
self.status = TimerRunning
def GetTimerStatus(self):
return self.status
# Keep objects in memory
activeTimers = []
Sample to initialize multiple timer instances:
for i in range(10, 0, -1):
timedObject = TimedObject("p1: " + str(i), "p2: " + str(i), "p3: " + str(i), i + 5)
timedObject.StartTimer()
# Ensure to keep in memory
activeTimers.append(timedObject)
-
Thanks Sovereign.
Just one thing though, perhaps i'm too dumb to see it, where do you actually call your function with its stored parameters?
I understand you create a class that stores some BC API class and call TimerSliceUpdate() after a delay.
Is it possible to see a snippet calling a function you defined? Say:
def CallMeWithMyArgs(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
-
What I gave you was a snippet to run multiple unrelated timers which "remember" certain parameters you provide. How you will handle your implementation after that point is up to you, generally it's all basic OOP stuff.
The following indicates that the timer is going to stop and is where you insert your logic.
def TimerSliceUpdate(self, fTime):
# Check if time slice process is running
if (self.status == TimerRunning):
# Kill instance
self.status = TimerStopped
global activeTimers
activeTimers.remove(self)
You can directly call a method, you can trigger an event or even this class can hold the implementation you want. It really depends on your approach and requirements.
-
I understand now.
Thanks :)
-
You could have just used a Timer Action.