v4k-git-backup/workbench/workbench.c

154 lines
4.0 KiB
C

// #define COOK_ON_DEMAND 1
// #define MAX_CACHED_FILES 0
// #define VFS_ALWAYS_PACK 1
#include "pluginapi.h"
array(editor_t) editors = 0;
array(asset_t) assets = 0;
#define PLUGINS\
X(shader_editor)
#define X(name) extern editor_vtable_t name##__procs;
PLUGINS
#undef X
editor_vtable_t load_editor_vtable(char *pname) {
char *name = va("%s.dll", pname);
editor_vtable_t f;
f.init = dll(name, "plug_init");
f.tick = dll(name, "plug_tick");
f.quit = dll(name, "plug_quit");
f.ext = dll(name, "plug_ext");
if (!f.init || !f.tick || !f.quit || !f.ext)
return (editor_vtable_t){0};
return f;
}
void load_editor(char *pname) {
editor_t ed = {0};
ed.name = file_base(STRDUP(pname)); // @leak
ed.f = load_editor_vtable(pname);
if (!ed.f.init) {
// PRINTF("unsupported plugin: '%s'\n", ed.name);
return;
}
PRINTF("loaded plugin: '%s'\n", ed.name);
array_push(editors, ed);
}
void load_editors() {
#define X(name) load_editor(#name);
PLUGINS
#undef X
}
map(char*, editor_t*) assocs;
void register_extensions() {
map_init(assocs, less_str, hash_str);
for (int i=0; i<array_count(editors); i++) {
char *types = editors[i].f.ext();
for each_substring(types, ",", ext) {
map_find_or_add(assocs, STRDUP(ext), (editors+i));
PRINTF("extension '%s' mapped to '%s'\n", ext, editors[i].name);
}
}
}
void edit_asset(char *fname) {
app_spawn(va("%s \"\" \"%s\"", ifdef(win32, "start", ifdef(osx, "open", "xdg-open")), fname));
}
void load_asset(const char *fname) {
char *ext = (file_ext(fname)+1);
PRINTF("opened asset: %s (%s)\n", fname, ext);
// see if we have a supported editor plugin registered
editor_t **ed = map_find(assocs, ext);
if (!ed) {
PRINTF("fallback exec %s\n", fname);
edit_asset(fname);
return;
}
asset_t asset = {0};
asset.name = STRDUP(fname);
asset.ed = *ed;
asset.opened = 1;
asset.last_modified = file_stamp(fname);
array_push(assets, asset);
if (asset.ed->f.init((struct asset_t*)array_back(assets))) {
FREE(asset.name);
array_pop(assets);
PRINTF("fallback exec %s\n", fname);
edit_asset(fname);
}
}
int main() {
window_create(75.0, WINDOW_MSAA8);
window_fps_unlock();
camera_t cam = camera();
camera_enable(&cam);
load_editors();
register_extensions();
#if 0
load_asset("demos/art/shadertoys/!default.fs");
load_asset("demos/art/fx/fxDithering.fs");
#endif
while( window_swap() && !input(KEY_ESC) ) {
if (ui_panel("Workbench", PANEL_OPEN)) {
static const char *file;
static bool show_browser = 1;
if( ui_browse(&file, &show_browser) ) {
load_asset(file);
show_browser = 1;
}
}
ui_panel_end();
// static bool show_main_window = 1;
// if ( ui_window("Workbench", &show_main_window) ) {
// ui_label("v4.games");
// }
// ui_window_end();
for (int i=0; i<array_count(assets); i++) {
asset_t *f = (assets+i);
if (ui_window(f->name, &f->opened)) {
f->ed->f.tick(f);
// was the asset modified?
bool modified = f->last_modified != file_stamp(f->name);
ui_separator();
if (ui_button("reload asset") || modified) {
f->last_modified = file_stamp(f->name);
f->ed->f.quit(f);
f->ed->f.init(f);
}
if (ui_button("edit asset")) {
edit_asset(assets[i].name);
}
if (ui_button("close asset") || !f->opened) {
f->ed->f.quit(f);
FREE(assets[i].name);
array_erase(assets, i);
--i;
}
}
ui_window_end();
}
}
return 0;
}