Difference between revisions of "Creating Multithreaded Skyrim Mods Part 3 - Callbacks"
Creating Multithreaded Skyrim Mods Part 3 - Callbacks (edit)
Revision as of 16:00, 22 January 2015
, 16:00, 22 January 2015Updated Thread section.
imported>Chesko (Added Futures tutorial as a template; will edit to fit Callbacks.) |
imported>Chesko (Updated Thread section.) |
||
Line 47: | Line 47: | ||
<source lang="papyrus"> | <source lang="papyrus"> | ||
scriptname GuardPlacementThread extends Quest hidden | scriptname GuardPlacementThread extends Quest hidden | ||
;Thread | ;Thread variables | ||
bool thread_queued = false | bool thread_queued = false | ||
;Variables you need to get things done go here | ;Variables you need to get things done go here | ||
ActorBase theGuard | ActorBase theGuard | ||
Static theMarker | Static theMarker | ||
;Thread queuing and set-up | ;Thread queuing and set-up | ||
ObjectReference function get_async( | ObjectReference function get_async(ActorBase akGuard, Static akXMarker) | ||
;Let the Thread Manager know that this thread is busy | |||
thread_queued = true | |||
;Store our passed-in parameters to member variables | |||
theGuard = akGuard | theGuard = akGuard | ||
theMarker = akXMarker | theMarker = akXMarker | ||
endFunction | endFunction | ||
;Allows the Thread Manager to determine if this thread is available | ;Allows the Thread Manager to determine if this thread is available | ||
bool function queued() | bool function queued() | ||
return thread_queued | return thread_queued | ||
endFunction | endFunction | ||
;For Thread Manager troubleshooting. | ;For Thread Manager troubleshooting. | ||
bool function force_unlock() | bool function force_unlock() | ||
Line 91: | Line 77: | ||
return true | return true | ||
endFunction | endFunction | ||
;The actual set of code we want to multithread. | ;The actual set of code we want to multithread. | ||
Event OnGuardPlacement() | Event OnGuardPlacement() | ||
if thread_queued | if thread_queued | ||
;OK, let's get some work done! | ;OK, let's get some work done! | ||
ObjectReference tempMarker = Game.GetPlayer().PlaceAtMe(theMarker) | ObjectReference tempMarker = Game.GetPlayer().PlaceAtMe(theMarker) | ||
MoveGuardMarkerNearPlayer(tempMarker) | MoveGuardMarkerNearPlayer(tempMarker) | ||
ObjectReference result = tempMarker.PlaceAtMe(theGuard) | ObjectReference result = tempMarker.PlaceAtMe(theGuard) | ||
tempMarker.Disable() | |||
tempMarker.Delete() | |||
;OK, we're done - raise event to return results | |||
RaiseEvent_GuardPlacementCallback(result) | |||
;Set all variables back to default | |||
clear_thread_vars() | clear_thread_vars() | ||
;Make the thread available to the Thread Manager again | |||
thread_queued = false | thread_queued = false | ||
endif | endif | ||
endEvent | endEvent | ||
; | ;Called from Event OnGuardPlacement | ||
function MoveGuardMarkerNearPlayer(ObjectReference akMarker) | function MoveGuardMarkerNearPlayer(ObjectReference akMarker) | ||
; | ;Move the marker away from the player a random distance and direction in 75.0 game unit increments | ||
Actor player = Game.GetPlayer() | |||
Float A = player.GetAngleZ() + (Utility.RandomInt(1, 24) * 15.0) | |||
Float YDist = math.Sin(A) | |||
Float XDist = math.Cos(A) | |||
XDist *= (Utility.RandomInt(1, 5) * 75.0) | |||
YDist *= (Utility.RandomInt(1, 5) * 75.0) | |||
akMarker.MoveTo(player, XDist, YDist) | |||
EndFunction | |||
function clear_thread_vars() | function clear_thread_vars() | ||
;Reset all thread variables to default state | ;Reset all thread variables to default state | ||
theGuard = None | theGuard = None | ||
theMarker = None | theMarker = None | ||
endFunction | |||
;Create the callback | |||
function RaiseEvent_GuardPlacementCallback(ObjectReference akGuard) | |||
int handle = ModEvent.Create("MyMod_GuardPlacementCallback") | |||
if handle | |||
ModEvent.PushForm(handle, akGuard as Form) | |||
ModEvent.Send(handle) | |||
else | |||
;pass | |||
endif | |||
endFunction | endFunction | ||
</source> | </source> | ||
Line 130: | Line 133: | ||
As you can see, our thread does a few important things: | As you can see, our thread does a few important things: | ||
* It has a <code>get_async()</code> function, which takes in all of the parameters necessary to do the work we need to perform. | * It has a <code>get_async()</code> function, which takes in all of the parameters necessary to do the work we need to perform. | ||
* <code>Event OnGuardPlacement()</code> will fire if the Thread Manager raises the event. | * <code>Event OnGuardPlacement()</code> will fire if the Thread Manager raises the event. | ||
* The thread | * The thread "calls back" to any scripts that have registered for our callback event. | ||
* It clears all of the member variables using <code>clear_thread_vars()</code>. | * It clears all of the member variables using <code>clear_thread_vars()</code>. |