Space Engineers

Space Engineers

[TMC] Tree Menu Command NET
cheerkin  [developer] 28 May, 2022 @ 9:52am
Advanced guide - dynamic menu population
Intro

The TMC can pull data from other scripts to populate menu nodes. The data goes by IGC system and that other script needs to be compatible (it should be able to answer TMC request in a certain way).

Users

S.C.A.M.

command:get-toggles:{igc.me} would populate the menu with current toggle states.
DisplayName=Mining system;scam-pb DisplayName=Toggles;command:get-toggles:{igc.me}

Orbital Painter

command:get-available-screens:{igc.me} - gets local grid LCD screens and binds current opened file to selected screen
command:get-available-files:{igc.me} - gets files from OP Storage and opens selected item (command:fopen:filename)

HudDog

command:get-toggles:{igc.me} would populate the menu with current toggle states.

Programmers

To make a script compatible it needs to send reply to TMC via IGC Unicast in the following format:

IGC tag: $"menucommand.get-commands.reply:{ tmcNode }" where tmcNode - is the node that was the request origin (i.e. command:get-toggles:1231231343243453)

IGC data type: ImmutableArray<MyTuple<string, string>>, where Item1 goes to DisplayName, Item2 goes to actual command.

Example of get-toggles implementation:

Dictionary<string, bool> sw; // tmcNode echoes back something like "command:get-toggles:1231231343243453" public ImmutableArray<MyTuple<string, string>> GetToggleCommands(string tmcNode) { return sw.Select(n => new MyTuple<string, string>($"{n.Key}: {(n.Value ? "on" : "off")}", $"[toggle:{n.Key}],[{tmcNode}]")).ToImmutableArray(); }

The snippet above would generate menu command items looking like this:
[toggle:aim],[command:get-toggles:1231231343243453]

So a script using this code should be able to run a batch command
[command1],[command2],[commandN]

The idea is that the script gets two commands from TMC action at once - first switches the toggle, and second requests items immediately after that, so that menu collection would be re-populated reflecting updated data state. You don't need it to work exactly this way, it's just my approach.

"get-toggles", (parts) => { var tmcNode = string.Join(":", parts.Take(3)); IGC.SendUnicastMessage(long.Parse(parts[2]), $"menucommand.get-commands.reply:{ tmcNode }", Toggle.C.GetToggleCommands(tmcNode)); // parts here is an array from argument string split by ':', e.g. "command:get-toggles:321312312" }
Last edited by cheerkin; 29 May, 2022 @ 4:24am