no longer need to send ids to window renderer; per actor config
This commit is contained in:
@@ -1,21 +1,13 @@
|
||||
sdl_video = "main"
|
||||
[dependencies]
|
||||
extramath = "https://gitea.pockle.world/john/extramath@master"
|
||||
|
||||
[system]
|
||||
# seconds before idle actor reclamation
|
||||
ar_timer = 60
|
||||
|
||||
# MB of memory an actor can use; 0 for unbounded
|
||||
actor_memory = 0
|
||||
|
||||
# seconds per net service pull
|
||||
net_service = 0.1
|
||||
|
||||
# seconds to hold callback for reply messages; 0 for unbounded
|
||||
reply_timeout = 60
|
||||
|
||||
# max number of simultaneous actors
|
||||
actor_max = 10_000
|
||||
|
||||
# MB of memory each actor's stack can grow to
|
||||
actor_memory = 0
|
||||
net_service = 0.1
|
||||
reply_timeout = 60
|
||||
actor_max = "10_000"
|
||||
stack_max = 0
|
||||
[actors]
|
||||
[actors.prosperon/sdl_video]
|
||||
main = true
|
||||
@@ -5,6 +5,8 @@ var draw2d = use('prosperon/draw2d')
|
||||
|
||||
var blob = use('blob')
|
||||
|
||||
log.console("HERE")
|
||||
|
||||
/*──── import our pieces + systems ───────────────────────────────────*/
|
||||
var Grid = use('grid'); // your new ctor
|
||||
var MovementSystem = use('movement').MovementSystem;
|
||||
@@ -277,7 +279,6 @@ function draw()
|
||||
draw2d.clear()
|
||||
drawBoard()
|
||||
drawPieces()
|
||||
draw2d.text("HELL", {x: 100, y: 100}, 'fonts/c64.ttf', 16, [1,1,1,1])
|
||||
return draw2d.get_commands()
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ rectangle packing, etc.
|
||||
`
|
||||
|
||||
var renderer_actor = arg[0]
|
||||
var renderer_id = arg[1]
|
||||
|
||||
var io = use('io')
|
||||
var time = use('time')
|
||||
@@ -43,7 +42,6 @@ Object.defineProperties(graphics.Image.prototype, {
|
||||
// Send message to load texture
|
||||
send(renderer_actor, {
|
||||
kind: "renderer",
|
||||
id: renderer_id,
|
||||
op: "loadTexture",
|
||||
data: this[CPU]
|
||||
}, function(response) {
|
||||
@@ -349,7 +347,6 @@ graphics.get_font = function get_font(path, size) {
|
||||
// Load font texture via renderer actor (async)
|
||||
send(renderer_actor, {
|
||||
kind: "renderer",
|
||||
id: renderer_id,
|
||||
op: "loadTexture",
|
||||
data: font.surface
|
||||
}, function(response) {
|
||||
|
||||
@@ -2,7 +2,28 @@ var os = use('os');
|
||||
var io = use('io');
|
||||
var transform = use('transform');
|
||||
var rasterize = use('rasterize');
|
||||
var video_actor = use('sdl_video')
|
||||
|
||||
var game = args[0]
|
||||
|
||||
var video
|
||||
|
||||
$_.start(e => {
|
||||
if (e.type !== 'greet') return
|
||||
video = e.actor
|
||||
graphics = use('graphics', video)
|
||||
send(video, {kind:"window", op:"makeRenderer"}, e => {
|
||||
$_.start(e => {
|
||||
if (gameactor) return
|
||||
gameactor = e.actor
|
||||
loop()
|
||||
}, args[0])
|
||||
})
|
||||
}, 'prosperon/sdl_video', {
|
||||
title: "Prosperon",
|
||||
width:500,
|
||||
height:500
|
||||
})
|
||||
|
||||
var input = use('input')
|
||||
|
||||
input.watch($_)
|
||||
@@ -77,49 +98,9 @@ var cammy = util.camera_globals(camera)
|
||||
|
||||
var graphics
|
||||
|
||||
var window
|
||||
var render
|
||||
|
||||
var gameactor
|
||||
|
||||
var game = args[0]
|
||||
|
||||
$_.start(e => {
|
||||
if (gameactor) return
|
||||
gameactor = e.actor
|
||||
loop()
|
||||
}, args[0])
|
||||
|
||||
send(video_actor, {
|
||||
kind: "window",
|
||||
op:"create",
|
||||
data: {
|
||||
title: "Moth Test",
|
||||
width: 500,
|
||||
height: 500
|
||||
}
|
||||
}, e => {
|
||||
if (e.error) {
|
||||
log.error(e.error)
|
||||
os.exit(1)
|
||||
}
|
||||
|
||||
window = e.id
|
||||
|
||||
send(video_actor,{
|
||||
kind:"window",
|
||||
op:"makeRenderer",
|
||||
id:window
|
||||
}, e => {
|
||||
if (e.error) {
|
||||
log.error(e.error)
|
||||
os.exit(1)
|
||||
}
|
||||
|
||||
render = e.id
|
||||
graphics = use('graphics', video_actor, e.id)
|
||||
})
|
||||
})
|
||||
|
||||
var last = os.now()
|
||||
|
||||
@@ -262,8 +243,9 @@ function translate_draw_commands(commands) {
|
||||
return renderer_commands
|
||||
}
|
||||
|
||||
function loop()
|
||||
function loop(time)
|
||||
{
|
||||
$_.delay(loop, 1/60)
|
||||
os.frame()
|
||||
var now = os.now()
|
||||
var dt = now - last
|
||||
@@ -295,9 +277,8 @@ function loop()
|
||||
op: "present"
|
||||
})
|
||||
|
||||
send(video_actor, {
|
||||
send(video, {
|
||||
kind: "renderer",
|
||||
id: render,
|
||||
op: "batch",
|
||||
data: batch_commands
|
||||
}, _ => {
|
||||
@@ -320,14 +301,13 @@ function loop()
|
||||
// Calculate average FPS
|
||||
var avg_fps = fps_sum / fps_samples.length
|
||||
}
|
||||
|
||||
loop()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
$_.receiver(e => {
|
||||
log.console(json.encode(e))
|
||||
if (e.type === 'quit')
|
||||
$_.stop()
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
var io = use('io')
|
||||
|
||||
Object.defineProperty(Function.prototype, "hashify", {
|
||||
value: function () {
|
||||
var hash = new Map()
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
var video = use('sdl_video');
|
||||
|
||||
// SDL Video Actor
|
||||
// This actor runs on the main thread and handles all SDL video operations
|
||||
var surface = use('surface')
|
||||
var surface = use('surface');
|
||||
|
||||
var ren
|
||||
var win
|
||||
|
||||
// Default window configuration - documents all available window options
|
||||
var default_window = {
|
||||
// Basic properties
|
||||
title: "Prosperon Window",
|
||||
@@ -53,10 +57,11 @@ var default_window = {
|
||||
textInput: true, // Enable text input on creation
|
||||
};
|
||||
|
||||
var config = Object.assign({}, default_window, arg[0] || {});
|
||||
win = new video.window(config);
|
||||
|
||||
// Resource tracking
|
||||
var resources = {
|
||||
window: {},
|
||||
renderer: {},
|
||||
texture: {},
|
||||
surface: {},
|
||||
cursor: {}
|
||||
@@ -115,26 +120,10 @@ $_.receiver(function(msg) {
|
||||
|
||||
// Window operations
|
||||
function handle_window(msg) {
|
||||
// Special case: create doesn't need an existing window
|
||||
if (msg.op === 'create') {
|
||||
var config = Object.assign({}, default_window, msg.data || {});
|
||||
var id = allocate_id();
|
||||
var window = new prosperon.endowments.window(config);
|
||||
resources.window[id] = window;
|
||||
return {id: id, data: {size: window.size}};
|
||||
}
|
||||
|
||||
// All other operations require a valid window ID
|
||||
if (!msg.id || !resources.window[msg.id]) {
|
||||
return {error: "Invalid window id: " + msg.id};
|
||||
}
|
||||
|
||||
var win = resources.window[msg.id];
|
||||
|
||||
switch (msg.op) {
|
||||
case 'destroy':
|
||||
win.destroy();
|
||||
delete resources.window[msg.id];
|
||||
win = undefined
|
||||
return {success: true};
|
||||
|
||||
case 'show':
|
||||
@@ -211,10 +200,10 @@ function handle_window(msg) {
|
||||
return {success: true};
|
||||
|
||||
case 'makeRenderer':
|
||||
var renderer = win.make_renderer();
|
||||
var renderer_id = allocate_id();
|
||||
resources.renderer[renderer_id] = renderer;
|
||||
return {id: renderer_id};
|
||||
if (ren)
|
||||
return {reason: "Already made a renderer"}
|
||||
ren = win.make_renderer()
|
||||
return {success:true};
|
||||
|
||||
default:
|
||||
return {error: "Unknown window operation: " + msg.op};
|
||||
@@ -223,33 +212,11 @@ function handle_window(msg) {
|
||||
|
||||
// Renderer operations
|
||||
function handle_renderer(msg) {
|
||||
// Special case: createWindowAndRenderer creates both
|
||||
if (msg.op === 'createWindowAndRenderer') {
|
||||
var data = msg.data || {};
|
||||
var result = prosperon.endowments.createWindowAndRenderer(
|
||||
data.title || "Prosperon Window",
|
||||
data.width || 640,
|
||||
data.height || 480,
|
||||
data.flags || 0
|
||||
);
|
||||
var win_id = allocate_id();
|
||||
var ren_id = allocate_id();
|
||||
resources.window[win_id] = result.window;
|
||||
resources.renderer[ren_id] = result.renderer;
|
||||
return {window_id: win_id, renderer_id: ren_id};
|
||||
}
|
||||
|
||||
// All other operations require a valid renderer ID
|
||||
if (!msg.id || !resources.renderer[msg.id]) {
|
||||
return {error: "Invalid renderer id: " + msg.id};
|
||||
}
|
||||
|
||||
var ren = resources.renderer[msg.id];
|
||||
|
||||
if (!ren) return{reason:'no renderer!'}
|
||||
|
||||
switch (msg.op) {
|
||||
case 'destroy':
|
||||
delete resources.renderer[msg.id];
|
||||
// Renderer is automatically destroyed when all references are gone
|
||||
ren = undefined
|
||||
return {success: true};
|
||||
|
||||
case 'clear':
|
||||
@@ -268,22 +235,6 @@ function handle_renderer(msg) {
|
||||
var prop = msg.data ? msg.data.property : null;
|
||||
if (!prop) return {error: "Missing property name"};
|
||||
|
||||
// Handle special cases
|
||||
if (prop === 'window') {
|
||||
var win = ren.window;
|
||||
if (!win) return {data: null};
|
||||
// Find window ID
|
||||
for (var id in resources.window) {
|
||||
if (resources.window[id] === win) {
|
||||
return {data: id};
|
||||
}
|
||||
}
|
||||
// Window not tracked, add it
|
||||
var win_id = allocate_id();
|
||||
resources.window[win_id] = win;
|
||||
return {data: win_id};
|
||||
}
|
||||
|
||||
// Handle special getters that might return objects
|
||||
if (prop === 'drawColor') {
|
||||
var color = ren[prop];
|
||||
@@ -300,6 +251,8 @@ function handle_renderer(msg) {
|
||||
var value = msg.value
|
||||
if (!prop) return {error: "Missing property name"};
|
||||
|
||||
if (!value) return {error: "No value to set"}
|
||||
|
||||
// Validate property is settable
|
||||
var readonly = ['window', 'name', 'outputSize', 'currentOutputSize', 'logicalPresentationRect', 'safeArea'];
|
||||
if (readonly.indexOf(prop) !== -1) {
|
||||
@@ -462,29 +415,11 @@ function handle_renderer(msg) {
|
||||
return {data: ren.coordsToWindow(msg.data.pos)};
|
||||
|
||||
case 'batch':
|
||||
// Execute a batch of operations
|
||||
if (!msg.data || !Array.isArray(msg.data)) return {error: "Missing or invalid data array"};
|
||||
|
||||
var results = [];
|
||||
for (var i = 0; i < msg.data.length; i++) {
|
||||
var cmd = msg.data[i];
|
||||
if (!cmd.op) {
|
||||
results.push({error: "Command at index " + i + " missing op"});
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a temporary message object for the command
|
||||
var temp_msg = {
|
||||
kind: 'renderer',
|
||||
id: msg.id,
|
||||
op: cmd.op,
|
||||
prop: cmd.prop,
|
||||
value: cmd.value,
|
||||
data: cmd.data
|
||||
};
|
||||
|
||||
// Recursively call handle_renderer for each command
|
||||
var result = handle_renderer(temp_msg);
|
||||
var result = handle_renderer(msg.data[i]);
|
||||
results.push(result);
|
||||
}
|
||||
|
||||
@@ -510,11 +445,11 @@ function handle_texture(msg) {
|
||||
if (msg.data.surface_id) {
|
||||
var surf = resources.surface[msg.data.surface_id];
|
||||
if (!surf) return {error: "Invalid surface id"};
|
||||
tex = new prosperon.endowments.texture(renderer, surf);
|
||||
tex = new video.texture(renderer, surf);
|
||||
}
|
||||
// Create from properties
|
||||
else if (msg.data.width && msg.data.height) {
|
||||
tex = new prosperon.endowments.texture(renderer, {
|
||||
tex = new video.texture(renderer, {
|
||||
width: msg.data.width,
|
||||
height: msg.data.height,
|
||||
format: msg.data.format || 'rgba8888',
|
||||
@@ -611,7 +546,7 @@ function handle_cursor(msg) {
|
||||
var surf = new surface(msg.data)
|
||||
|
||||
var hotspot = msg.data.hotspot || [0, 0];
|
||||
var cursor = prosperon.endowments.createCursor(surf, hotspot);
|
||||
var cursor = video.createCursor(surf, hotspot);
|
||||
|
||||
var cursor_id = allocate_id();
|
||||
resources.cursor[cursor_id] = cursor;
|
||||
@@ -622,7 +557,7 @@ function handle_cursor(msg) {
|
||||
if (msg.id && resources.cursor[msg.id]) {
|
||||
cursor = resources.cursor[msg.id];
|
||||
}
|
||||
prosperon.endowments.setCursor(cursor);
|
||||
video.setCursor(cursor);
|
||||
return {success: true};
|
||||
|
||||
case 'destroy':
|
||||
@@ -642,7 +577,7 @@ prosperon.endowments = prosperon.endowments || {};
|
||||
|
||||
// Mouse operations
|
||||
function handle_mouse(msg) {
|
||||
var mouse = prosperon.endowments.mouse;
|
||||
var mouse = video.mouse;
|
||||
|
||||
switch (msg.op) {
|
||||
case 'show':
|
||||
@@ -736,7 +671,7 @@ function handle_mouse(msg) {
|
||||
|
||||
// Keyboard operations
|
||||
function handle_keyboard(msg) {
|
||||
var keyboard = prosperon.endowments.keyboard;
|
||||
var keyboard = video.keyboard;
|
||||
|
||||
switch (msg.op) {
|
||||
case 'get_state':
|
||||
@@ -256,6 +256,24 @@ globalThis.json = use('json')
|
||||
globalThis.text = use('text')
|
||||
var time = use('time')
|
||||
|
||||
// Load actor-specific configuration
|
||||
function load_actor_config(program) {
|
||||
// Extract actor name from program path
|
||||
// e.g., "prosperon/_sdl_video" or "extramath/spline"
|
||||
var actor_name = program
|
||||
if (program.includes('/')) {
|
||||
actor_name = program
|
||||
}
|
||||
|
||||
if (config.actors && config.actors[actor_name]) {
|
||||
// Merge actor config into cell.args
|
||||
for (var key in config.actors[actor_name]) {
|
||||
log.console(`setting ${key}`)
|
||||
cell.args[key] = config.actors[actor_name][key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var blob = use('blob')
|
||||
|
||||
function deepFreeze(object) {
|
||||
@@ -627,6 +645,10 @@ function turn(msg)
|
||||
send_messages()
|
||||
}
|
||||
|
||||
load_actor_config(cell.args.program)
|
||||
|
||||
log.console(`actor ${cell.args.program} is ${cell.args.main}`)
|
||||
|
||||
actor_mod.register_actor(cell.id, turn, cell.args.main, config.system.ar_timer)
|
||||
|
||||
if (config.system.actor_memory)
|
||||
@@ -751,6 +773,9 @@ function enet_check()
|
||||
// Finally, run the program
|
||||
actor_mod.setname(cell.args.program)
|
||||
|
||||
// Load actor-specific configuration before running
|
||||
|
||||
|
||||
var prog = null
|
||||
var progPath = cell.args.program
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ if (io.exists(cell_man)) {
|
||||
log.console(" vendor Copy all dependencies locally")
|
||||
log.console(" build Compile all modules to bytecode")
|
||||
log.console(" patch Create a patch for a module")
|
||||
log.console(" config Manage system and actor configurations")
|
||||
log.console(" help Show this help message")
|
||||
log.console("")
|
||||
log.console("Run 'cell help <command>' for more information on a command.")
|
||||
|
||||
@@ -323,7 +323,7 @@ int prosperon_mount_core(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
cell_rt *create_actor(void *wota, void (*hook)(JSContext*))
|
||||
cell_rt *create_actor(void *wota)
|
||||
{
|
||||
cell_rt *actor = calloc(sizeof(*actor), 1);
|
||||
actor->init_wota = wota;
|
||||
@@ -341,7 +341,7 @@ cell_rt *create_actor(void *wota, void (*hook)(JSContext*))
|
||||
|
||||
/* Lock actor->mutex while initializing JS runtime. */
|
||||
SDL_LockMutex(actor->mutex);
|
||||
script_startup(actor, hook);
|
||||
script_startup(actor);
|
||||
SDL_UnlockMutex(actor->mutex);
|
||||
|
||||
set_actor_state(actor);
|
||||
@@ -702,7 +702,7 @@ static int actor_interrupt_cb(JSRuntime *rt, cell_rt *crt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void script_startup(cell_rt *prt, void (*hook)(JSContext*))
|
||||
void script_startup(cell_rt *prt)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
#ifdef TRACY_ENABLE
|
||||
@@ -747,10 +747,6 @@ void script_startup(cell_rt *prt, void (*hook)(JSContext*))
|
||||
PHYSFS_close(eng);
|
||||
data[stat.filesize] = 0;
|
||||
|
||||
/* Call hook function if provided before evaluating engine */
|
||||
if (hook)
|
||||
hook(js);
|
||||
|
||||
/* Called with actor->mutex locked by create_actor(). */
|
||||
JSValue v = JS_Eval(js, data, (size_t)stat.filesize, ENGINE, JS_EVAL_FLAG_STRICT);
|
||||
uncaught_exception(js, v);
|
||||
@@ -1582,7 +1578,7 @@ int main(int argc, char **argv)
|
||||
wota_write_array(&startwota, actor_argc - 1);
|
||||
for (int i = 1; i < actor_argc; i++)
|
||||
wota_write_text(&startwota, actor_argv[i]);
|
||||
root_cell = create_actor(startwota.data, NULL);
|
||||
root_cell = create_actor(startwota.data);
|
||||
|
||||
/* Launch runner threads */
|
||||
for (int i = 0; i < cores; i++) {
|
||||
|
||||
@@ -79,7 +79,7 @@ extern SDL_TLSID prosperon_id;
|
||||
|
||||
extern cell_rt *root_cell; // first actor in the system
|
||||
|
||||
cell_rt *create_actor(void *wota, void (*hook)(JSContext*));
|
||||
cell_rt *create_actor(void *wota);
|
||||
const char *register_actor(const char *id, cell_rt *actor, int mainthread, double ar);
|
||||
void actor_disrupt(cell_rt *actor);
|
||||
|
||||
@@ -87,7 +87,7 @@ const char *send_message(const char *id, void *msg);
|
||||
Uint32 actor_timer_cb(cell_rt *actor, SDL_TimerID id, Uint32 interval);
|
||||
JSValue js_actor_delay(JSContext *js, JSValue self, int argc, JSValue *argv);
|
||||
JSValue js_actor_removetimer(JSContext *js, JSValue self, int argc, JSValue *argv);
|
||||
void script_startup(cell_rt *rt, void (*hook)(JSContext*));
|
||||
void script_startup(cell_rt *rt);
|
||||
void script_evalf(JSContext *js, const char *format, ...);
|
||||
JSValue script_eval(JSContext *js, const char *file, const char *script);
|
||||
int uncaught_exception(JSContext *js, JSValue v);
|
||||
|
||||
@@ -75,7 +75,7 @@ JSValue actor2js(JSContext *js, cell_rt *actor)
|
||||
|
||||
JSC_CCALL(os_createactor,
|
||||
void *startup = value2wota(js, argv[0], JS_UNDEFINED);
|
||||
create_actor(startup, NULL);
|
||||
create_actor(startup);
|
||||
)
|
||||
|
||||
JSC_CCALL(os_mailbox_push,
|
||||
|
||||
@@ -1744,12 +1744,13 @@ JSC_CCALL(sdl_createWindowAndRenderer,
|
||||
return ret;
|
||||
)
|
||||
|
||||
// Hook function to set up endowments for the video actor
|
||||
static void video_actor_hook(JSContext *js) {
|
||||
// Get prosperon object
|
||||
JSValue global = JS_GetGlobalObject(js);
|
||||
JSValue prosperon = JS_GetPropertyStr(js, global, "prosperon");
|
||||
JS_FreeValue(js,global);
|
||||
#include "qjs_wota.h"
|
||||
|
||||
JSValue js_sdl_video_use(JSContext *js) {
|
||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||
return JS_ThrowInternalError(js, "Unable to initialize video subsystem: %s", SDL_GetError());
|
||||
|
||||
JSValue ret = JS_NewObject(js);
|
||||
|
||||
// Initialize classes
|
||||
QJSCLASSPREP_FUNCS(SDL_Window)
|
||||
@@ -1769,50 +1770,19 @@ static void video_actor_hook(JSContext *js) {
|
||||
// Set prototype on constructor
|
||||
JS_SetConstructor(js, texture_ctor, SDL_Texture_proto);
|
||||
|
||||
// Get or create endowments object
|
||||
JSValue endowments = JS_GetPropertyStr(js, prosperon, "endowments");
|
||||
if (JS_IsUndefined(endowments)) {
|
||||
endowments = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, prosperon, "endowments", JS_DupValue(js, endowments));
|
||||
}
|
||||
|
||||
// Set constructors in endowments
|
||||
JS_SetPropertyStr(js, endowments, "window", window_ctor);
|
||||
JS_SetPropertyStr(js, endowments, "texture", texture_ctor);
|
||||
JS_SetPropertyStr(js, ret, "window", window_ctor);
|
||||
JS_SetPropertyStr(js, ret, "texture", texture_ctor);
|
||||
|
||||
// Add utility function
|
||||
JS_SetPropertyStr(js, endowments, "createWindowAndRenderer",
|
||||
JS_SetPropertyStr(js, ret, "createWindowAndRenderer",
|
||||
JS_NewCFunction(js, js_sdl_createWindowAndRenderer, "createWindowAndRenderer", 4));
|
||||
|
||||
// Add cursor functions
|
||||
JS_SetPropertyStr(js, endowments, "createCursor",
|
||||
JS_NewCFunction(js, js_sdl_create_cursor, "createCursor", 2));
|
||||
JS_SetPropertyStr(js, endowments, "setCursor",
|
||||
JS_NewCFunction(js, js_sdl_set_cursor, "setCursor", 1));
|
||||
JS_SetPropertyStr(js, ret, "createCursor",
|
||||
JS_NewCFunction(js, js_sdl_create_cursor, "createCursor", 2));
|
||||
JS_SetPropertyStr(js, ret, "setCursor",
|
||||
JS_NewCFunction(js, js_sdl_set_cursor, "setCursor", 1));
|
||||
|
||||
JS_FreeValue(js, endowments);
|
||||
JS_FreeValue(js, prosperon);
|
||||
}
|
||||
|
||||
#include "qjs_wota.h"
|
||||
|
||||
JSValue js_sdl_video_use(JSContext *js) {
|
||||
if (!SDL_Init(SDL_INIT_VIDEO))
|
||||
return JS_ThrowInternalError(js, "Unable to initialize video subsystem: %s", SDL_GetError());
|
||||
|
||||
// Generate a unique ID for the video actor
|
||||
char id[64];
|
||||
snprintf(id, sizeof(id), "video_%llu", (unsigned long long)SDL_GetTicks());
|
||||
|
||||
JSValue startup = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,startup, "id", JS_NewStringLen(js,id,64));
|
||||
JS_SetPropertyStr(js,startup, "program", JS_NewString(js,"prosperon/_sdl_video"));
|
||||
JS_SetPropertyStr(js,startup,"main",JS_NewBool(js,1));
|
||||
|
||||
void *wota = value2wota(js,startup, JS_UNDEFINED);
|
||||
|
||||
JS_FreeValue(js,startup);
|
||||
|
||||
cell_rt *actor = create_actor(wota, video_actor_hook);
|
||||
return actor2js(js,actor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user