Embedding a toplevel

I’m looking to embed an ocaml Toplevel within my application. To wit, I’m writing Godot 4.2 bindings and looking to add the ability to stop the world and execute code from the toplevel. That is, control passes from Godot to OCaml, which executes a toplevel, which after you’re done you C-d from and control passes back to whatever OCaml code called the toplevel (and presumably back to Godot), hopefully with the effects on any global refs still visible. I can’t imagine this is a novel idea but I’m having trouble googling around for how to embed a toplevel in a (native shared_object) (which the Godot extension must be compiled as).

Any help would be appreciated!

That sounds maybe difficult. It depends whether the terminal is inside or outside of Godot since the toplevel requires a terminal.

Terminal inside Godot? More difficult. If you use something like GitHub - lihop/godot-xterm: Terminal emulator for the Godot game engine. inside Godot, that has its own complexity and on top of that you’d have to bind the terminal events to a toplevel. If you do want that path the “simplest” (ie. very much not simple but doable) would be to adapt the down toplevel. I started down this path for a similar need (didn’t finish it); have a look at @nojb 's Initial support for Win32 by nojb · Pull Request #35 · dbuenzli/down · GitHub for how to bind an unusual terminal (ie. godot-xterm) to a toplevel.

If the terminal is outside, a simple form of RPC (ex. HTTP over localhost or domain socket) between a thread in your toplevel and a thread in Godot would work, right?

In between you have a wide range of options. If you are stuck on the more complex side of options, I am going to combine my scripting framework DkCoder with DkSDK FFI C for embedding scenarios at some point. But for now I’d suggest just keeping it simple with RPC.

Thanks @jbeckford for the information. Kind of surprising that a drop in solution doesn’t exist, but that’s life!

Matt

Running a toplevel doesn’t have to require a terminal. You can build your own UI in Godot which calls (native) execute_phrase directly, passing it a formatter which interprets pretty-printing directives as you need.

control passes back to whatever OCaml code called the toplevel (and presumably back to Godot), hopefully with the effects on any global refs still visible

This should be possible if you build your own Toploop which then yields to Godot. The state of the toplevel environment is kept in Topcommon.toplevel_env, which execute_phrase mutates, so no extra work needs to be done to preserve the state.

2 Likes

Thanks @dariusf, I will check it out!