Parallel Tasker is a plugin for Unity (see Test) and Kerbal Space Program that can execute supplied tasks in parallel between any possible combination of defined times (see Task Timing below). Parallel Tasker is expected to be used through ParallelTasker.ParallelTasker
as a hard dependency for other plugins. Times are determined by script execution orders of PTSynchronizers and exported in Asset Bundle synchronizers.pt (yes, asset bundles also export script execution orders). This offers a very lightweight and consistent method to signalize timings of Update events. In addition, Parallel Tasker does not generate any garbage while executing tasks except for creating new ones (removed tasks are reused). If no tasks need to be started or ended at a specific time, then that task controller is unsubscribed from receiving the synchronizer events. All classes are defined in ParallelTasker
namespace.
The API can be found in a static ParallelTasker
class.
bool ResetTasksOnSceneChange
: a property to disable/enable task clearing on scene changes (KSP) to be used in case some tasks rely onGameObject
s that may no longer be available in different scenes. Default:true
bool SubscriptionStatus(PTTimePair taskGroup)
: synchronizer subscription status of task controller that runs at timetaskGroup
.bool SubscriptionStatus(PTUpdateEvent updateEvent, PTEventTime eventTime)
: overload of the above.void Subscribe(PTTimePair timePair, Action handler)
: subscribehandler
to receivetimePair
update event, remove withUnsubscribe
otherwise thehandler
may not be garbage collected.void Subscribe(PTUpdateEvent updateEvent, PTEventTime eventTime, Action handler)
: overload of the above.void Unsubscribe(PTTimePair timePair, Action handler)
: unsubscribehandler
from receiving update events attimePair
time.void Unsubscribe(PTUpdateEvent updateEvent, PTEventTime eventTime, Action handler)
: overload of the above.
Adding a task requires a start startTime
and end endTime
time defined by PTTimePair
. Removing a specific task only requires its startTime
since that is where it is registered internally. Note that (for now) the startTime
is not referenced in PTTask
.
PTTask AddTask(PTTimePair startTime, PTTimePair endTime, PTTask task)
: add a tasktask
to be executed in timing groupgroup
, returns the added task, in this casetask
PTTask AddTask(PTTimePair startTime, PTTimePair endTime, Func<object, object> task, uint period = 1)
: add a task with noinitialize
andfinalize
with execution periodperiod
to the current task list. Returns the added task.PTTask AddTask(PTTimePair startTime, PTTimePair endTime, Func<object> initializer, Func<object, object> task, uint period = 1)
: add a task withfinalize
with execution periodperiod
to the current task list. Returns the added task.PTTask AddTask(PTTimePair startTime, PTTimePair endTime, Func<object, object> task, Action<object> finalizer, uint period = 1)
: add a task with noinitialize
with execution periodperiod
to the current task list. Returns the added task.PTTask AddTask(PTTimePair startTime, PTTimePair endTime, Func<object> initializer, Func<object, object> task, Action<object> finalizer, uint period = 1)
: add a complete task with execution periodperiod
to the current task list. Returns the added task.bool RemoveTask(PTTimePair startTime, PTTask task)
: removetask
fromgroup
task list. Returns success/failure of removal.bool RemoveTask(PTTimePair startTime, Func<object, object> task)
: remove the first task withPTTask.main == task
from thegroup
task list. Returns success/failure of removal.void ClearTasks()
: clear all current tasks.void ClearTasks(PTTimePair startTime)
: clear all tasks starting atstartTime
time.
Logs are flushed every frame at LateUpdate.Start
. Logging API is similar to Unity's but does not contain overloads with UnityEngine.Object
arguments since Unity API is not thread safe and thus should not be used in multi threading. Use sparingly since most tasks will be executed 10s of times per second.
void Debug(object message)
: log a normalmessage
, only if compiled withDEBUG
.void DebugFormat(string format, params object[] args)
: log a formattedformat
message with argumentsargs
, only if compiled withDEBUG
.void Log(object message)
: log a normalmessage
.void LogFormat(string format, params object[] args)
: log a formattedformat
message with argumentsargs
.void LogError(object message)
: log an errormessage
.void LogErrorFormat(string format, params object[] args)
: log a formatted errorformat
message with argumentsargs
.void LogWarning(object message)
: log a warningmessage
.void LogWarningFormat(string format, params object[] args)
: log a formatted warningformat
message with argumentsargs
.void LogException(Exception exception)
: log an exceptionexception
.
Parallel Tasker consists of 3 Update events PTUpdateEvent
and 9 possible timers PTEventTime
. Any possible combination of those values is a valid start or end time for the task. Though mixing FixedUpdate
with Update
or LateUpdate
may not make much sense since they run on different timers. Each combination of timing is guaranteed to finish the tasks ending at that time before starting new ones. If start and end times are equal, the task will be finished in the next Update event. Any task with an end time before start time will finish in the next Update event (i.e. start in LateUpdate
and end in Update
or end with a lower PTEventTime
)
They are standard Unity Update events:
public enum PTUpdateEvent
{
Update,
LateUpdate,
FixedUpdate
}
Current timers are based on KSP Script Execution Order:
public enum PTEventTime
{
Start = -8008,
Precalc = -101,
Early = -99,
Earlyish = -1,
Normal = 0,
FashionablyLate = 7,
FlightIntegrator = 9,
Late = 19,
End = 8008
}
The default dequeue order depends on Enum.GetValues(Type)
so it may change in the future. It currently is:
- Update.Normal
- Update.FashionablyLate
- Update.FlightIntegrator
- Update.Late
- Update.End
- Update.Start
- Update.Precalc
- Update.Early
- Update.Earlyish
- LateUpdate.Normal
- LateUpdate.FashionablyLate
- LateUpdate.FlightIntegrator
- LateUpdate.Late
- LateUpdate.End
- LateUpdate.Start
- LateUpdate.Precalc
- LateUpdate.Early
- LateUpdate.Earlyish
- FixedUpdate.Normal
- FixedUpdate.FashionablyLate
- FixedUpdate.FlightIntegrator
- FixedUpdate.Late
- FixedUpdate.End
- FixedUpdate.Start
- FixedUpdate.Precalc
- FixedUpdate.Early
- FixedUpdate.Earlyish
Tasks that need to be ended are given priority.
Each task PTTask
can be queued for any of the start and end times and consists of 3 functions, unsigned integer and PTTimePair
:
Func<object> initialize
(optional): a function that returnsobject
, guaranteed to run before any other task function. This can be used to copy data from the main thread to be passed tomain
. It is always executed on the main thread.Func<object, object> main
: a function that takes a singleobject
(frominitialize
) as an argument and returnsobject
. This function is executed in a different thread and thus should be made thread safe. Guaranteed to run afterinitialize
and beforefinalize
of this task.Action<object> finalize
(optional): a void function that takes a singleobject
(frommain
) as an argument, guaranteed to be executed afterinitialize
andmain
. Always executed on the main thread. This can be used to copy data from the thread back to the main thread.uint period
: how often this task is executed, i.e.period
of 1 will execute this task on every Update event. Default: 1.PTTimePair EndTime
: read only (until dynamic subscription can be made to work consistently) end time of this task (one ofPTUpdateEvent
andPTEventTime
combinations).