Matrix Games Forums

Forums  Register  Login  Photo Gallery  Member List  Search  Calendars  FAQ 

My Profile  Inbox  Address Book  My Subscription  My Forums  Log Out

How to pause script execution without pausing the scenario/C:MO thread?

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [New Releases from Matrix Games] >> Command: Modern Operations series >> Mods and Scenarios >> Lua Legion >> How to pause script execution without pausing the scenario/C:MO thread? Page: [1]
Login
Message << Older Topic   Newer Topic >>
How to pause script execution without pausing the scena... - 7/22/2021 12:16:49 AM   
Fido81

 

Posts: 109
Joined: 7/14/2019
Status: online
What's the C:MO API correct way to force lua to take time between executing lines of a script?

I want a unit currently in a state of OutOfComms="True" to become OutOfComms="False", wait for 15 seconds, and then become OutOfComms="True".
Post #: 1
RE: How to pause script execution without pausing the s... - 7/22/2021 7:42:26 AM   
musurca

 

Posts: 89
Joined: 7/16/2020
Status: offline
I've dealt with this issue quite a bit--there are a few different approaches that you can take. The "easiest" and most CMO-specific way is to dynamically create a new Event which triggers a script at a specific date and time in the scenario (see the Command Lua documentation for the trigger type called "Time"). Unfortunately setting up a dynamic event is a bit unwieldy, and there are some weird and undocumented issues related to how the time value is encoded. Here's a function which should handle them:

----
function WaitFor(seconds, script)
local function uuid()
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
return string.gsub(template, '[xy]', function (c)
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
return string.format('%x', v)
end)
end

-- add these special magic numbers. don't ask why.
local run_epoch = (62135596800 + ScenEdit_CurrentTime() + seconds) * 10000000

local evt_name = uuid()
ScenEdit_SetEvent(
evt_name,
{
mode='add',
IsRepeatable=false,
IsShown=false
}
)

local trigger_name = uuid()
ScenEdit_SetTrigger(
{
name=trigger_name,
mode='add',
type='Time',
Time=run_epoch
}
)

local action_name = uuid()
ScenEdit_SetAction(
{
name=action_name,
mode='add',
type='LuaScript',
ScriptText=script
}
)

ScenEdit_SetEventTrigger(
evt_name,
{
mode='add',
name=trigger_name
}
)
ScenEdit_SetEventAction(
evt_name,
{
mode='add',
name=action_name
}
)
end

-----

Example usage:

SetUnitComms(my_unit_guid, True)
WaitFor(15, "SetUnitComms(my_unit_guid, False)")

-----
(A better version of this function would clean up after itself to avoid leaving dead events in the list, but I leave that as an exercise for the reader.)


A slightly more flexible approach would be to use Lua coroutines instead. In that version, you would have a coroutine manager that runs every second and iterates through a stack of active coroutines which would yield to wait a second of sim time. However I wouldn't bother if you're not familar with coroutines and won't be needing this pattern often.

< Message edited by musurca -- 7/22/2021 7:48:56 AM >

(in reply to Fido81)
Post #: 2
RE: How to pause script execution without pausing the s... - 7/22/2021 1:52:10 PM   
KnightHawk75

 

Posts: 1198
Joined: 11/15/2018
Status: offline
quote:


-- add these special magic numbers. don't ask why.
local run_epoch = (62135596800 + ScenEdit_CurrentTime() + seconds) * 10000000


You might as well explain it.
The time in time events is store in .net Tick Time is why.
There are 10 million ticks per second in that format.
.net TickTime's epoch is 1/1/0001:0:0:0 vs the unix epoc of 1/1/1970:0:0:0 (used for scene time)
There have been 621355968000000000 ticks from 1/1/0001:0:0:0 to 1/1/1970:0:0:0 (the unix epoch)

-- Pair of converstion function for .net epoch tick time vs typical unix epoch seconds time.
function convertDotNetTickTimeToLuaTimestamp(theDotNetStamp)
return (tonumber(theDotNetStamp) - 621355968000000000) / 10000000
end

function convertLuaTimestampToDotNetTickTime(theUnixStamp)
return 621355968000000000 + (tonumber(theUnixStamp) * 10000000)
end


coroutines... not to mention if it's not a private scene, no nice way to always stop and clean them up properly if a user just decides to up and load another scene mid-execution. One of the issues with the lua environment not being wiped per scenario in CMO, and why I'm in favor of a sort of scene_unload event that can be trapped for proper cleanup.

(in reply to musurca)
Post #: 3
RE: How to pause script execution without pausing the s... - 7/22/2021 6:24:31 PM   
musurca

 

Posts: 89
Joined: 7/16/2020
Status: offline
quote:

You might as well explain it.

Thank you, this is a great explanation! (And should probably be copied directly to the documentation. Currently it just describes the field as the "Actual date/time to fire on.")

While we're advocating new features --I would enthusiastically vote for your proposal for a scene_unload hook-- I would also suggest a structure to unify how time is handled. Currently there are no less than three different representations of time used in the CMO API: Unix epoch time, "DateTime" (a structure with two fields holding locale-specific date and time strings), and DotNet ticks (which is only used here, as far as I know, and is weird since an event which can at most fire once per second probably doesn't need a granularity of 10M fractional ticks). This can lead to a lot of wasted time and footguns.

I assume this inconsistency has arisen for legacy-support reasons as the API has evolved--which is why I would propose some kind of unifying Time wrapper which could be in any of those formats internally, but has a consistent outward representation for the user and can be converted to whatever format is required at the time. For any field in which time is required, you could pass it this wrapper and it would just work.

(in reply to KnightHawk75)
Post #: 4
RE: How to pause script execution without pausing the s... - 7/23/2021 5:05:01 PM   
Parel803

 

Posts: 436
Joined: 10/10/2019
From: Netherlands
Status: offline
Thx all for explaining stuff. Much appreciated.
with regards Gert-Jan

(in reply to musurca)
Post #: 5
Page:   [1]
All Forums >> [New Releases from Matrix Games] >> Command: Modern Operations series >> Mods and Scenarios >> Lua Legion >> How to pause script execution without pausing the scenario/C:MO thread? Page: [1]
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts


Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI

0.180