nesbox / TIC-80

TIC-80 is a fantasy computer for making, playing and sharing tiny games.
https://tic80.com
MIT License
4.94k stars 479 forks source link

Live reload of .lua file(s) in developer mode #299

Closed fmaida closed 6 years ago

fmaida commented 6 years ago

When I open a specific .p8 file in Pico-8 and I'm editing that same .p8 file in Atom, I can modify the file and when I save it, Pico-8 acknowledges that the file has been modified and reloads it on the fly (without showing again the boot sequence / startup animation).

I use Visual Studio Code and the TIC-80 plugin to edit TIC-80 files; I know that it is possible to enter a sort of "developer mode" and edit externally a .lua file by launching TIC-80 from the command line with the instruction:

tic cart.tic -code game.lua

But when I modify and save back the game.lua, I have to manually close and reopen TIC-80 in order to see applied changes I've made to the file.

Would it be possible to have TIC-80 wait for changes on a file and then reload? Basically, I'd like to:

1) Launch TIC with the command tic cart.tic -code game.lua 2) Edit game.lua with Visual Studio Code or any other code editor 3) Save game.lua 4) See TIC-80 that immediately reload the cart and runs it with the modifications I've just made

That would be really handy and a huge time saver IMHO

nesbox commented 6 years ago

will do, thanks

fmaida commented 6 years ago

Thank you very much.

Maybe if you could also implement this... since there are probably people that would prefer to manually control TIC-80 behaviour, could you allow users to enable or disable this feature from the command line when they launch the app? For example by writing something like this:

tic cart.tic -code game.lua -watch

vamolessa commented 6 years ago

Could this be of help? https://emcrisostomo.github.io/fswatch/

vamolessa commented 6 years ago

Oh, maybe we could get a code reload when regaining focus. That could be simpler and we'd use the SDL event SDL_WINDOWEVENT_FOCUS_GAINED. I was trying to do that yesterday but I'm yet to figure out how to reload code.

vamolessa commented 6 years ago

@nesbox you think this (link) would be a good solution?

I added this windows focus event to studio.c that will try to trigger code reload:

case SDL_WINDOWEVENT_FOCUS_GAINED:
    {
        studio.console.codeLiveReload.reload(&studio.console,studio.code.data);
        if(studio.code.update)
            studio.code.update(&studio.code);
    }
break;

The code loading from file code was extracted from cmdInjectCode() and put into loadFileIntoBuffer(). This way it is now possible to be reused in tryReloadCode (everything inside console.c:

static void tryReloadCode(Console* console, char* codeBuffer)
{
    if(console->codeLiveReload.active)
    {
        const char* fileName = console->codeLiveReload.fileName;
        loadFileIntoBuffer(console, codeBuffer, fileName);
    }
}

Console now has an anonymous struct codeLiveReload:

struct
{
    char fileName[FILENAME_MAX];
    bool active;

    void(*reload)(Console*, char*);
} codeLiveReload;

That reload points to tryReloadCode.

Then I'm not sure if the code is in the correct place. Since the original code injection was done in console.c I thought I should put the live code reloading there too.

Feedback would be appreciated :)

vamolessa commented 6 years ago

Oh, forgot to say that the "-watch" option is not yet implemented. Trying to figure out the base code first.

nesbox commented 6 years ago

@matheuslessarodrigues I think console.c is a good place to Live Reloading

one thing, please move memset(buffer, 0, TIC_CODE_SIZE); https://github.com/nesbox/TIC-80/compare/tic_0.47.0...matheuslessarodrigues:tic_0.47.0?expand=1#diff-0e2533ce03d5884282bd8f8980a3a2ecR2285

to

if(contents)
{ ...

block (you are erasing the code buffer while a file isn't loaded)

nesbox commented 6 years ago

done