CSharpRepl icon indicating copy to clipboard operation
CSharpRepl copied to clipboard

Trying to use it in Godot Engine and some feature requests

Open Odaimoko opened this issue 8 months ago • 0 comments

Feature Description

Hi waf. I've been trying to incorporate CSharpRepl into my Godot game. I tweak the source code to overcome some of the technical problems with Godot. I wonder if some of them can be implemented in the official repo.

My architecture is to run a http server within the Godot game, in which CSharpRepl is used to only run the code. Then I use a CSharpRepl console as a client sending actual code to the Godot game to execute. They have the same references and imports.

Here are some tweaks I made to make it work.

  1. Godot API calls are wrappers around actual C++ functions. We should reference additional assemblies in ScriptRunner.CreateSuccessfulResult, and add dependencies to ScriptRunner.assemblyLoader, as talked about here.
  2. We can only run some non-thread-safe Godot API in the main thread. Thus, we need a configurable ConfigureAwait(true/false) behaviour, especially for executing the actual piece of code.
  3. There will be no arguments returned by Environment.GetCommandLineArgs(), and accessing RootCommand.ExecutablePath causes exception. We need a customizable RootCommand.
  4. Add a event handler to customize code evaluation in ReadEvalPrintLoop, and a command line configuration to prevent the client from executing the code.
  5. Make some classes and methods public in CSharpRepl.csproj

Here is the example piece for (4).

// Add a event handler
public event Func<string, Task<EvaluationResult>>? EvaluatingInput; 

 if (config.RunRoslyn)
{
    result = await roslyn
        .EvaluateAsync(response.Text, config.LoadScriptArgs, response.CancellationToken)
        .ConfigureAwait(true);
}
else if (EvaluatingInput != null)
{
    result = await EvaluatingInput.Invoke(response.Text);
}
else
{
    console.WriteErrorLine(
        $"[Eval] if {nameof(Configuration.RunRoslyn)} is false, please provide a runner via{nameof(EvaluatingInput)}");
    result = new EvaluationResult.Cancelled();
}

Looking forward to hear some suggestions.

Odaimoko avatar Jun 01 '25 14:06 Odaimoko