-
Notifications
You must be signed in to change notification settings - Fork 238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamically loading mods on platforms x-cli-* #522
Comments
You are close. You can use Inside XS, mods are called archives. As you found, an archive needs to be memory mapped to be used. The way that is done is platform dependent. Once the mod is mapped, you should be able to do exactly what happens in
|
Thanks! While I have not given it much test time, it appears to be working now on Windows, and I see the path to getting it to work on Mac and Linux. I have a question about the event loop processing - after I start the exported default function (from the host) I simply terminate the app when it returns. Does the Moddable SDK somehow maintain the event loop until all code is done processing (including handling instrumentation sampling as appropriate), or do I need to take some action in my main.c code to ensure the event loop and instrumentation has processing cycles? |
Congrats!
The Moddable SDK performs no magic. ;) The host is responsible for the event loop, if you want one at all (command line tools, for example, do not). Different hosts have different ideas about what it means for "until all code is done processing". The REPL, for example, just runs in an endless blocking loop. On macOS, a basic event loop is pretty easy: int main(int argc, char* argv[])
{
xsMachine *the;
// ...initialize the
CFRunLoopRun();
xsDeleteMachine(the);
return 0;
} One way to terminate is to bind in a JavaScript function to exit the event loop: function exit() @ "xs_host_exit"; void xs_host_exit(xsMachine *the)
{
CFRunLoopStop(CFRunLoopGetCurrent());
} |
My goal here is to have the Perhaps I'm over thinking this, as the debugger does work, so something in the |
Keep in mind that... x-cli-* builds are different on purpose. They give you the ability to provide whatever host behavior you need. That's a feature. A powerful feature with a great deal of flexibility. It isn't intended to be easy. If you just want the simulator host behavior, use the simulator. ;) You can think of x-cli-* builds as the most general way to build. That generality means that there's less that the SDK can do for you. The macOS code above gives the basics of what I understand you want -- to launch from the command line and run until the script signals that it is complete. The same can be done for Windows and Linux.
Yes, they do. On ESP8266, it just uses the Arduino loop function. On ESP32, it uses a FreeRTOS task loop. The host for each platform is different.
Yes, they do this by periodically calling a sampling function. This is done from a native timer and so is host dependent.
This one you get from the SDK, because it has built-in support for debugging on macOS, Windows, and Linux.
But you still need some of that for the modules to work. For example, timers on macOS rely on the native event loop being active. Sockets too. |
That all makes sense, and confirms my basic understanding (thanks!). I think the gap for me remains how to establish the event loop from the perspective of XS and the SDK. I took a look at the ESP8266 implementation and loop()... it does the following:
This appears to mostly prime the pump for timer and not much else. Is that all the XS modules require to work from the event loop? I see that the
Do you mean that if my host needs the event loop I need to keep it running, or do you mean XS needs it (such as for sockets)? My gut right now says that all XS (and the Moddable SDK modules) needs is the timer to be fed, and everything else with the event loop is platform specific (which in my case, may be very little)? |
Never mind to the prior message - I figured it out. I now have a main() that starts a thread, which in turn starts the VM, manages the Windows message pump, and terminals the VM when a So now the next question is ... now that I own my own idle loop, I need to also own calling |
That's great news. All the device targets run instrumentation once per second. It isn't very much overhead, so you could do more, but for general use a second seems to work well.
|
Once/second sounds great - I have that working now as well. I understand Is it possible to detect if the debugger is connected? When I call |
#ifdef mxDebug
if (fxIsConnected(the))
...;
#endif |
@phoddie I've got Windows, Mac and Linux all working, and so far all examples I've tried (that don't need the screen) are working as well (assuming they work at all on the native platform). However, I'm finding an issue calling this I am also finding it's hard to constrain it to just Therefore, I propose we add a new platform type of Taking this approach would maintain the What's your thoughts on this approach? It will take a bit to instrument, but seems cleaner with less risk of breaking existing code. |
I'm not sure about using a separate platform target for here. If I understand well, this is basically a I'd like to make sure I understand how you intend to use this. This is clearly for projects that don't use a display. When you build those for a device, you'll specify a platform that doesn't include a display;
When you build for a computer, you want to run as a headless command line tool rather than launching the usual screen-based simulator. To achieve that, you'll do something like:
Is that close to correct? |
Yes, that's correct. The the reason I am proposing a new build target is that if I use By adding a new platform, these problems are avoided. Additionally, the manifests can be tuned for the unique features of the cli-based platform vs. x-cli (since cli supports event loops, promises, workers and dynamic mods). My thought was to continue with the current model, where At least that was my thinking! The pull is up there now if you want to look at it and see if it's useful to the project or not. I'll be using it for sure either way. |
I'll definitely take a look at the PR. I just wanted to understand the big picture first since it is easy to get lost in the details. I tend to think of build targets as a big thing -- certainly anything that involves cracking open the |
I think the PR is proof this issue has been addressed, so I'll close it out. |
I would like to be able to dynamically load a mod from inside a platform type of
x-cli-*
(such asx-cli-win
), similar to how microcontrollers can place a mod in the flashxs
partition and on reboot have the host and mod available for importing modules. My goal here is to dynamically load a mod from a cloud server, and execute it on both microcontrollers andx-cli-*
platforms.I have gotten the
x-cli-win
platform working, with my own custommain.c
file as follows (all from cut/paste of various code from Moddable):I don't understand what the
fxCloneMachine
call does, but my gut is I need to add some logic following that call, and before I attempt to import the module(s) usingxsAwaitImport
. My immediate goal is Windows, but I'll eventually need it to operate on Mac and Linux as well.Any hints on what I should be looking at to do this? I see in the Windows simulator (
simulator/win/main.cpp
line 698, infxScreenViewProc
handling theWM_LAUNCH_MACHINE
message) that it seems to open the file and map the file into memory space (CreateFileMapping
andMapViewOfFile
). Mac and Linux do something similar, but usingmmap
instead. After this, it goes into the SimulatorfxScreenLaunch
method (build/simulator/screen.c
line 241) that seems to do some work withxsPreparation
,fxMapArchive
, andfxPrepareMachine
that seem like they may be the trick to pulling all this together?The text was updated successfully, but these errors were encountered: