untoldwind / KontrolSystem2

Autopilot scripting system for KSP2
Other
54 stars 15 forks source link

Request to support simpler global variables #76

Closed RobertoBiundo closed 5 months ago

RobertoBiundo commented 1 year ago

While programming TO2 files it would be very useful that as a programing language it could support global variables within the file. This would allow programmers to store things like current vessel state. Or to enable starting and stopping a running task.

Example:

use { sleep } form ksp::game

let enableTelemetry = false

pub fn start_telemetry_loop() {
  enableTelemetry = true
  while(enableTelemetry) {
     sleep(0.5)
     // Log something to the console
  }
}

pub fn stop_telemetry_loop() {
  enableTelemtry = false
}

The caller of this functions could then enable and disable the telemetry without doing any internal operations or keeping track of things

EDIT The requested scenario is actually possible using Cells, the request has been changed to support a simpler way of using global variables

untoldwind commented 1 year ago

With async functions shared values are a somewhat tricky buisness. Right now you can use the Cell helper. Like this:

use { sleep } form ksp::game

const enableTelemetry : Cell<bool> = Cell(false)

pub fn start_telemetry_loop() {
  enableTelemetry.value = true
  while(enableTelemetry.value) {
     sleep(0.5)
     // Log something to the console
  }
}

pub fn stop_telemetry_loop() {
  enableTelemetry.value = false
}

i.e. the Cell is a constant, the value inside is not and can be changed in a thread-safe manner.

But it should be possible to make the syntax less clunky.

RobertoBiundo commented 1 year ago

Ah!...great it was not clear in the documentation to me at least. I've changed my request to "simpler" global variables

RobertoBiundo commented 1 year ago

Question. It looks to me that altough the functions are async the callers always implement an inherited await. (Sorry for the C# reference). How would I perform a fire and forget scenario where I can callt his start_telemetry_loop() and just continue with the rest of my execution?

untoldwind commented 1 year ago

Question. It looks to me that altough the functions are async the callers always implement an inherited await. (Sorry for the C# reference). How would I perform a fire and forget scenario where I can callt his start_telemetry_loop() and just continue with the rest of my execution?

Little bit of background info: The KontrolSystem scripts (or async functions) usually run as Unity-coroutine, so they are still in the same thread as the main game loop.

Currently there is no API to launch a secondary/child coroutine (though I am planing to add one eventually ... there are some nasty details to figure out). In the mean time it is possible to use core::background::run to run a sync function in a background thread (which is for example useful for long running calculation that would otherwise interfere with the game loop too much). Problem is: This actually starts a new thread and I have no idea what happens if you interact with the vessel API (or other game related things) ... collecting telemetry this way might work, but this has not been tested at all yet

lefouvert commented 8 months ago

version 0.5.2.6 (Ckan)

Hi,

Still have some question with glo variables : Are them cross module, or their «global» aspect is only on file scope ? (as it's a long and cluncky post, don't forget this question, it's the most valuable to me please ^^) If they are, how to, since I can't make this mechanic work ?

Also, I did try this : gitreport::cell.to2

use { Vessel } from ksp::vessel
use { CONSOLE } from ksp::console

struct Foo(vessel: Vessel) { bar: Vessel = vessel }
impl Foo { // some fancy methods
}

sync fn foobar(param: int[]) -> int[] = { param.reverse() } // side note : doc says 'revert' instead of 'reverse'

const fooberic: Cell<fn(int[]) -> int[]> = Cell(foobar()) // unsupported
const foobaristic: Cell<Option<Foo>> = Cell(None()) // unsupported

const foobaressive: Cell<Option<bool>> = Cell(None())
const operational: Cell<bool> = Cell(false)

pub fn main_flight(vessel: Vessel) -> Result<Unit, string> = {
    CONSOLE.clear()

    // this work :
    CONSOLE.print_line("'foobaressive' prior state: " + (if(foobaressive.value.defined) foobaressive.value.value.to_string() else "UNDEFINED"))
    foobaressive.value = Some(true)
    CONSOLE.print_line("'foobaressive' value brute: " + (if(foobaressive.value.defined) foobaressive.value.value.to_string() else "UNDEFINED"))
    foobaressive.update(fn(current) -> if(current.defined) !current.value)
    CONSOLE.print_line("'foobaressive' value trigg: " + (if(foobaressive.value.defined) foobaressive.value.value.to_string() else "UNDEFINED"))

    CONSOLE.print_line("-------------------")

    // this work too :
    CONSOLE.print_line("'operationnal' prior state: " + operational.value.to_string())
    operational.value = true
    CONSOLE.print_line("'operationnal' value brute: " + operational.value.to_string())
    operational.update(fn(current) -> !current)
    CONSOLE.print_line("'operationnal' value trigg: " + operational.value.to_string())
}

Error message (triggered by fooberic declaration) :

Rebooted in 00:00:03.3277914 ERROR: [gitreport\cell.to2(14, 1)] InvalidType Constant fooberic can not be initialized with type Cell ERROR: [gitreport\cell.to2(15, 1)] InvalidType Constant foobaressive can not be initialized with type Cell ERROR: [gitreport\cell.to2(16, 1)] InvalidType Constant operational can not be initialized with type Cell

Error message (triggered by foobaristic declaration) :

Rebooted in 00:00:02.5745006 ERROR: [(0, 0)] Unknown error Specified method is not supported.

What to consider :

Faulty code lines (comment them and it will compile) : const fooberic: Cell<fn(int[]) -> int[]> = Cell(foobar()) // unsupported const foobaristic: Cell<Option<Foo>> = Cell(None()) // unsupported

Edit : as always, typo

untoldwind commented 8 months ago

Instead of

const fooberic: Cell<fn(int[]) -> int[]> = Cell(foobar())

this should be correct:

const fooberic: Cell<fn(int[]) -> int[]> = Cell(foobar)

... the Cell<Option<Foo>> should be fixed in the next patch

lefouvert commented 8 months ago

Gasp ! Although I'm used to use function's pointer, I'm still grip with «I think function, I put parenthesis».

Still,

Are them cross module, or their «global» aspect is only on file scope ? (as it's a long and cluncky post, don't forget this question, it's the most valuable to me please ^^) If they are, how to, since I can't make this mechanic work ?

untoldwind commented 8 months ago

Maybe it helps to know what happens internally (most of this happens in the ModuleGenerator:

So there should be only one instance of a global variable floating around

github-actions[bot] commented 6 months ago

This issue is stale because it has been open for 60 days with no activity.

github-actions[bot] commented 5 months ago

This issue was closed because it has been inactive for 14 days since being marked as stale.