From 66c28e9b5f34485ecaa968c98180112dafe702d1 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Mon, 25 Aug 2025 12:07:14 -0500 Subject: [PATCH] rework scripted schedule signatures; add start_time and finish_time (#2344) --- .../Engine/ISchedulingEngineState.cs | 1 + .../ScriptedPlayoutBuilder.cs | 42 +++++++++++-------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/ErsatzTV.Core/Scheduling/Engine/ISchedulingEngineState.cs b/ErsatzTV.Core/Scheduling/Engine/ISchedulingEngineState.cs index b0f2bc3ab..b131c5344 100644 --- a/ErsatzTV.Core/Scheduling/Engine/ISchedulingEngineState.cs +++ b/ErsatzTV.Core/Scheduling/Engine/ISchedulingEngineState.cs @@ -10,6 +10,7 @@ public interface ISchedulingEngineState PlayoutBuildMode Mode { get; } int Seed { get; } DateTimeOffset CurrentTime { get; } + DateTimeOffset Start { get; } DateTimeOffset Finish { get; } // result diff --git a/ErsatzTV.Core/Scheduling/ScriptedScheduling/ScriptedPlayoutBuilder.cs b/ErsatzTV.Core/Scheduling/ScriptedScheduling/ScriptedPlayoutBuilder.cs index 735fb1217..02cd2af48 100644 --- a/ErsatzTV.Core/Scheduling/ScriptedScheduling/ScriptedPlayoutBuilder.cs +++ b/ErsatzTV.Core/Scheduling/ScriptedScheduling/ScriptedPlayoutBuilder.cs @@ -58,20 +58,8 @@ public class ScriptedPlayoutBuilder( engine.SetSearchPaths(paths); } - var sys = engine.GetSysModule(); - var modules = (PythonDictionary)sys.GetVariable("modules"); - - var types = engine.ImportModule("types"); - dynamic moduleType = types.GetVariable("ModuleType"); - - dynamic ersatztv = engine.Operations.Invoke(moduleType, "ersatztv"); - modules["ersatztv"] = ersatztv; - var contentModule = new ContentModule(schedulingEngine); - engine.Operations.SetMember(ersatztv, "content", contentModule); - var playoutModule = new PlayoutModule(schedulingEngine); - engine.Operations.SetMember(ersatztv, "playout", playoutModule); engine.ExecuteFile(playout.ScheduleFile, scope); @@ -82,8 +70,19 @@ public class ScriptedPlayoutBuilder( return result; } + if (defineContentFunc.__code__.co_argcount != 2) + { + logger.LogError("Script function 'define_content' must accept 2 parameters: (content, context)"); + return result; + } + // reset_playout is NOT required scope.TryGetVariable("reset_playout", out PythonFunction resetPlayoutFunc); + if (resetPlayoutFunc != null && resetPlayoutFunc.__code__.co_argcount != 2) + { + logger.LogError("Script function 'reset_playout' must accept 2 parameters: (playout, context)"); + return result; + } // build_playout is required if (!scope.TryGetVariable("build_playout", out PythonFunction buildPlayoutFunc)) @@ -92,21 +91,27 @@ public class ScriptedPlayoutBuilder( return result; } - schedulingEngine.RestoreOrReset(Optional(playout.Anchor)); + if (buildPlayoutFunc.__code__.co_argcount != 2) + { + logger.LogError("Script function 'build_playout' must accept 2 parameters: (playout, context)"); + return result; + } - // define content first - engine.Operations.Invoke(defineContentFunc); + schedulingEngine.RestoreOrReset(Optional(playout.Anchor)); var context = new PythonPlayoutContext(schedulingEngine.GetState(), playoutModule, engine); + // define content first + engine.Operations.Invoke(defineContentFunc, contentModule, context); + // reset if applicable if (mode is PlayoutBuildMode.Reset && resetPlayoutFunc != null) { - engine.Operations.Invoke(resetPlayoutFunc, context); + engine.Operations.Invoke(resetPlayoutFunc, playoutModule, context); } // build playout - engine.Operations.Invoke(buildPlayoutFunc, context); + engine.Operations.Invoke(buildPlayoutFunc, playoutModule, context); playout.Anchor = schedulingEngine.GetAnchor(); @@ -159,7 +164,8 @@ public class ScriptedPlayoutBuilder( } public object current_time => ToPythonDateTime(_state.CurrentTime); - //public object finish => ToPythonDateTime(_state.Finish); + public object start_time => ToPythonDateTime(_state.Start); + public object finish_time => ToPythonDateTime(_state.Finish); public bool is_done() {