render command ops
This commit is contained in:
@@ -88,6 +88,9 @@ $_.receiver(function(msg) {
|
|||||||
case 'texture':
|
case 'texture':
|
||||||
response = handle_texture(msg);
|
response = handle_texture(msg);
|
||||||
break;
|
break;
|
||||||
|
case 'surface':
|
||||||
|
response = handle_surface(msg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
response = {error: "Unknown kind: " + msg.kind};
|
response = {error: "Unknown kind: " + msg.kind};
|
||||||
}
|
}
|
||||||
@@ -101,65 +104,107 @@ $_.receiver(function(msg) {
|
|||||||
|
|
||||||
// Window operations
|
// Window operations
|
||||||
function handle_window(msg) {
|
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) {
|
switch (msg.op) {
|
||||||
case '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: {width: window.width, height: window.height}};
|
|
||||||
|
|
||||||
case 'destroy':
|
case 'destroy':
|
||||||
if (!msg.id || !resources.window[msg.id]) {
|
win.destroy();
|
||||||
return {error: "Invalid window id: " + msg.id};
|
|
||||||
}
|
|
||||||
resources.window[msg.id].destroy();
|
|
||||||
delete resources.window[msg.id];
|
delete resources.window[msg.id];
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
case 'show':
|
case 'show':
|
||||||
if (!msg.id || !resources.window[msg.id]) {
|
win.visible = true;
|
||||||
return {error: "Invalid window id: " + msg.id};
|
|
||||||
}
|
|
||||||
resources.window[msg.id].show();
|
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
case 'hide':
|
case 'hide':
|
||||||
if (!msg.id || !resources.window[msg.id]) {
|
win.visible = false;
|
||||||
return {error: "Invalid window id: " + msg.id};
|
|
||||||
}
|
|
||||||
resources.window[msg.id].hide();
|
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
case 'set_title':
|
case 'get':
|
||||||
if (!msg.id || !resources.window[msg.id]) {
|
var prop = msg.data ? msg.data.property : null;
|
||||||
return {error: "Invalid window id: " + msg.id};
|
if (!prop) return {error: "Missing property name"};
|
||||||
|
|
||||||
|
// Handle special cases
|
||||||
|
if (prop === 'surface') {
|
||||||
|
var surf = win.surface;
|
||||||
|
if (!surf) return {data: null};
|
||||||
|
var surf_id = allocate_id();
|
||||||
|
resources.surface[surf_id] = surf;
|
||||||
|
return {data: surf_id};
|
||||||
}
|
}
|
||||||
if (!msg.data || !msg.data.title) {
|
|
||||||
return {error: "Missing title in data"};
|
return {data: win[prop]};
|
||||||
|
|
||||||
|
case 'set':
|
||||||
|
var prop = msg.data ? msg.data.property : null;
|
||||||
|
var value = msg.data ? msg.data.value : undefined;
|
||||||
|
if (!prop) return {error: "Missing property name"};
|
||||||
|
|
||||||
|
// Validate property is settable
|
||||||
|
var readonly = ['id', 'pixelDensity', 'displayScale', 'sizeInPixels', 'flags', 'surface'];
|
||||||
|
if (readonly.indexOf(prop) !== -1) {
|
||||||
|
return {error: "Property '" + prop + "' is read-only"};
|
||||||
}
|
}
|
||||||
resources.window[msg.id].title = msg.data.title;
|
|
||||||
|
win[prop] = value;
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
case 'get_size':
|
case 'fullscreen':
|
||||||
if (!msg.id || !resources.window[msg.id]) {
|
win.fullscreen();
|
||||||
return {error: "Invalid window id: " + msg.id};
|
|
||||||
}
|
|
||||||
var win = resources.window[msg.id];
|
|
||||||
return {data: {width: win.width, height: win.height}};
|
|
||||||
|
|
||||||
case 'set_size':
|
|
||||||
if (!msg.id || !resources.window[msg.id]) {
|
|
||||||
return {error: "Invalid window id: " + msg.id};
|
|
||||||
}
|
|
||||||
if (!msg.data || typeof msg.data.width !== 'number' || typeof msg.data.height !== 'number') {
|
|
||||||
return {error: "Missing or invalid width/height in data"};
|
|
||||||
}
|
|
||||||
var win = resources.window[msg.id];
|
|
||||||
win.width = msg.data.width;
|
|
||||||
win.height = msg.data.height;
|
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
|
case 'updateSurface':
|
||||||
|
win.updateSurface();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'updateSurfaceRects':
|
||||||
|
if (!msg.data || !msg.data.rects) return {error: "Missing rects array"};
|
||||||
|
win.updateSurfaceRects(msg.data.rects);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'raise':
|
||||||
|
win.raise();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'restore':
|
||||||
|
win.restore();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'flash':
|
||||||
|
win.flash(msg.data ? msg.data.operation : 'briefly');
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'sync':
|
||||||
|
win.sync();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'setIcon':
|
||||||
|
if (!msg.data || !msg.data.surface_id) return {error: "Missing surface_id"};
|
||||||
|
var surf = resources.surface[msg.data.surface_id];
|
||||||
|
if (!surf) return {error: "Invalid surface id"};
|
||||||
|
win.set_icon(surf);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'makeRenderer':
|
||||||
|
var renderer = win.make_renderer();
|
||||||
|
var renderer_id = allocate_id();
|
||||||
|
resources.renderer[renderer_id] = renderer;
|
||||||
|
return {id: renderer_id};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {error: "Unknown window operation: " + msg.op};
|
return {error: "Unknown window operation: " + msg.op};
|
||||||
}
|
}
|
||||||
@@ -167,41 +212,233 @@ function handle_window(msg) {
|
|||||||
|
|
||||||
// Renderer operations
|
// Renderer operations
|
||||||
function handle_renderer(msg) {
|
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];
|
||||||
|
|
||||||
switch (msg.op) {
|
switch (msg.op) {
|
||||||
case 'create':
|
|
||||||
if (!msg.data || !msg.data.window_id) {
|
|
||||||
return {error: "Missing window_id in data"};
|
|
||||||
}
|
|
||||||
if (!resources.window[msg.data.window_id]) {
|
|
||||||
return {error: "Invalid window id: " + msg.data.window_id};
|
|
||||||
}
|
|
||||||
var id = allocate_id();
|
|
||||||
var renderer = prosperon.endowments.renderer.create(resources.window[msg.data.window_id]);
|
|
||||||
resources.renderer[id] = renderer;
|
|
||||||
return {id: id};
|
|
||||||
|
|
||||||
case 'destroy':
|
case 'destroy':
|
||||||
if (!msg.id || !resources.renderer[msg.id]) {
|
|
||||||
return {error: "Invalid renderer id: " + msg.id};
|
|
||||||
}
|
|
||||||
resources.renderer[msg.id].destroy();
|
|
||||||
delete resources.renderer[msg.id];
|
delete resources.renderer[msg.id];
|
||||||
|
// Renderer is automatically destroyed when all references are gone
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
case 'clear':
|
case 'clear':
|
||||||
if (!msg.id || !resources.renderer[msg.id]) {
|
ren.clear();
|
||||||
return {error: "Invalid renderer id: " + msg.id};
|
|
||||||
}
|
|
||||||
resources.renderer[msg.id].clear();
|
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
case 'present':
|
case 'present':
|
||||||
if (!msg.id || !resources.renderer[msg.id]) {
|
ren.present();
|
||||||
return {error: "Invalid renderer id: " + msg.id};
|
|
||||||
}
|
|
||||||
resources.renderer[msg.id].present();
|
|
||||||
return {success: true};
|
return {success: true};
|
||||||
|
|
||||||
|
case 'flush':
|
||||||
|
ren.flush();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'get':
|
||||||
|
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];
|
||||||
|
if (color && typeof color === 'object') {
|
||||||
|
// Convert color object to array format [r,g,b,a]
|
||||||
|
return {data: [color.r || 0, color.g || 0, color.b || 0, color.a || 255]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {data: ren[prop]};
|
||||||
|
|
||||||
|
case 'set':
|
||||||
|
var prop = msg.prop
|
||||||
|
var value = msg.value
|
||||||
|
if (!prop) return {error: "Missing property name"};
|
||||||
|
|
||||||
|
// Validate property is settable
|
||||||
|
var readonly = ['window', 'name', 'outputSize', 'currentOutputSize', 'logicalPresentationRect', 'safeArea'];
|
||||||
|
if (readonly.indexOf(prop) !== -1) {
|
||||||
|
return {error: "Property '" + prop + "' is read-only"};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special handling for render target
|
||||||
|
if (prop === 'target' && value !== null && value !== undefined) {
|
||||||
|
var tex = resources.texture[value];
|
||||||
|
if (!tex) return {error: "Invalid texture id"};
|
||||||
|
value = tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
ren[prop] = value;
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'line':
|
||||||
|
if (!msg.data || !msg.data.points) return {error: "Missing points array"};
|
||||||
|
ren.line(msg.data.points);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'point':
|
||||||
|
if (!msg.data || !msg.data.points) return {error: "Missing points"};
|
||||||
|
ren.point(msg.data.points);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'rect':
|
||||||
|
if (!msg.data || !msg.data.rect) return {error: "Missing rect"};
|
||||||
|
ren.rect(msg.data.rect);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'fillRect':
|
||||||
|
if (!msg.data || !msg.data.rect) return {error: "Missing rect"};
|
||||||
|
ren.fillRect(msg.data.rect);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'rects':
|
||||||
|
if (!msg.data || !msg.data.rects) return {error: "Missing rects"};
|
||||||
|
ren.rects(msg.data.rects);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'lineTo':
|
||||||
|
if (!msg.data || !msg.data.a || !msg.data.b) return {error: "Missing points a and b"};
|
||||||
|
ren.lineTo(msg.data.a, msg.data.b);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'texture':
|
||||||
|
if (!msg.data) return {error: "Missing texture data"};
|
||||||
|
var tex_id = msg.data.texture_id;
|
||||||
|
if (!tex_id || !resources.texture[tex_id]) return {error: "Invalid texture id"};
|
||||||
|
ren.texture(
|
||||||
|
resources.texture[tex_id],
|
||||||
|
msg.data.src || {x:0, y:0, w:1, h:1},
|
||||||
|
msg.data.dst || {x:0, y:0, w:100, h:100},
|
||||||
|
msg.data.angle || 0,
|
||||||
|
msg.data.anchor || {x:0.5, y:0.5}
|
||||||
|
);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'sprite':
|
||||||
|
if (!msg.data || !msg.data.sprite) return {error: "Missing sprite data"};
|
||||||
|
ren.sprite(msg.data.sprite);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'geometry':
|
||||||
|
if (!msg.data) return {error: "Missing geometry data"};
|
||||||
|
var tex_id = msg.data.texture_id;
|
||||||
|
var tex = tex_id ? resources.texture[tex_id] : null;
|
||||||
|
ren.geometry(tex, msg.data.geometry);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'debugText':
|
||||||
|
if (!msg.data || !msg.data.text) return {error: "Missing text"};
|
||||||
|
ren.debugText(msg.data.pos || {x:0, y:0}, msg.data.text);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'clipEnabled':
|
||||||
|
return {data: ren.clipEnabled()};
|
||||||
|
|
||||||
|
case 'texture9Grid':
|
||||||
|
if (!msg.data) return {error: "Missing data"};
|
||||||
|
var tex_id = msg.data.texture_id;
|
||||||
|
if (!tex_id || !resources.texture[tex_id]) return {error: "Invalid texture id"};
|
||||||
|
ren.texture9Grid(
|
||||||
|
resources.texture[tex_id],
|
||||||
|
msg.data.src,
|
||||||
|
msg.data.leftWidth,
|
||||||
|
msg.data.rightWidth,
|
||||||
|
msg.data.topHeight,
|
||||||
|
msg.data.bottomHeight,
|
||||||
|
msg.data.scale,
|
||||||
|
msg.data.dst
|
||||||
|
);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'textureTiled':
|
||||||
|
if (!msg.data) return {error: "Missing data"};
|
||||||
|
var tex_id = msg.data.texture_id;
|
||||||
|
if (!tex_id || !resources.texture[tex_id]) return {error: "Invalid texture id"};
|
||||||
|
ren.textureTiled(
|
||||||
|
resources.texture[tex_id],
|
||||||
|
msg.data.src,
|
||||||
|
msg.data.scale || 1.0,
|
||||||
|
msg.data.dst
|
||||||
|
);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'readPixels':
|
||||||
|
var surf = ren.readPixels(msg.data ? msg.data.rect : null);
|
||||||
|
if (!surf) return {error: "Failed to read pixels"};
|
||||||
|
var surf_id = allocate_id();
|
||||||
|
resources.surface[surf_id] = surf;
|
||||||
|
return {id: surf_id};
|
||||||
|
|
||||||
|
case 'loadTexture':
|
||||||
|
if (!msg.data || !msg.data.surface_id) return {error: "Missing surface_id"};
|
||||||
|
var surf = resources.surface[msg.data.surface_id];
|
||||||
|
if (!surf) return {error: "Invalid surface id"};
|
||||||
|
var tex = ren.load_texture(surf);
|
||||||
|
var tex_id = allocate_id();
|
||||||
|
resources.texture[tex_id] = tex;
|
||||||
|
return {id: tex_id};
|
||||||
|
|
||||||
|
case 'createTexture':
|
||||||
|
if (!msg.data || !msg.data.width || !msg.data.height) {
|
||||||
|
return {error: "Missing width or height"};
|
||||||
|
}
|
||||||
|
var tex = ren.createTexture(
|
||||||
|
msg.data.format || 'rgba8888',
|
||||||
|
msg.data.access || 'static',
|
||||||
|
msg.data.width,
|
||||||
|
msg.data.height
|
||||||
|
);
|
||||||
|
if (!tex) return {error: "Failed to create texture"};
|
||||||
|
var tex_id = allocate_id();
|
||||||
|
resources.texture[tex_id] = tex;
|
||||||
|
return {id: tex_id, data: {size: tex.size}};
|
||||||
|
|
||||||
|
case 'flush':
|
||||||
|
ren.flush();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'coordsFromWindow':
|
||||||
|
if (!msg.data || !msg.data.pos) return {error: "Missing pos"};
|
||||||
|
return {data: ren.coordsFromWindow(msg.data.pos)};
|
||||||
|
|
||||||
|
case 'coordsToWindow':
|
||||||
|
if (!msg.data || !msg.data.pos) return {error: "Missing pos"};
|
||||||
|
return {data: ren.coordsToWindow(msg.data.pos)};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {error: "Unknown renderer operation: " + msg.op};
|
return {error: "Unknown renderer operation: " + msg.op};
|
||||||
}
|
}
|
||||||
@@ -209,12 +446,120 @@ function handle_renderer(msg) {
|
|||||||
|
|
||||||
// Texture operations
|
// Texture operations
|
||||||
function handle_texture(msg) {
|
function handle_texture(msg) {
|
||||||
|
// Special case: create needs a renderer
|
||||||
|
if (msg.op === 'create') {
|
||||||
|
if (!msg.data) return {error: "Missing texture data"};
|
||||||
|
var ren_id = msg.data.renderer_id;
|
||||||
|
if (!ren_id || !resources.renderer[ren_id]) return {error: "Invalid renderer id"};
|
||||||
|
|
||||||
|
var tex;
|
||||||
|
var renderer = resources.renderer[ren_id];
|
||||||
|
|
||||||
|
// Create from surface
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
// Create from properties
|
||||||
|
else if (msg.data.width && msg.data.height) {
|
||||||
|
tex = new prosperon.endowments.texture(renderer, {
|
||||||
|
width: msg.data.width,
|
||||||
|
height: msg.data.height,
|
||||||
|
format: msg.data.format || 'rgba8888',
|
||||||
|
pixels: msg.data.pixels,
|
||||||
|
pitch: msg.data.pitch
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {error: "Must provide either surface_id or width/height"};
|
||||||
|
}
|
||||||
|
|
||||||
|
var tex_id = allocate_id();
|
||||||
|
resources.texture[tex_id] = tex;
|
||||||
|
return {id: tex_id, data: {size: tex.size}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other operations require a valid texture ID
|
||||||
|
if (!msg.id || !resources.texture[msg.id]) {
|
||||||
|
return {error: "Invalid texture id: " + msg.id};
|
||||||
|
}
|
||||||
|
|
||||||
|
var tex = resources.texture[msg.id];
|
||||||
|
|
||||||
switch (msg.op) {
|
switch (msg.op) {
|
||||||
case 'create':
|
case 'destroy':
|
||||||
// TODO: Implement texture creation
|
delete resources.texture[msg.id];
|
||||||
return {error: "Texture operations not yet implemented"};
|
// Texture is automatically destroyed when all references are gone
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'get':
|
||||||
|
var prop = msg.data ? msg.data.property : null;
|
||||||
|
if (!prop) return {error: "Missing property name"};
|
||||||
|
return {data: tex[prop]};
|
||||||
|
|
||||||
|
case 'set':
|
||||||
|
var prop = msg.data ? msg.data.property : null;
|
||||||
|
var value = msg.data ? msg.data.value : undefined;
|
||||||
|
if (!prop) return {error: "Missing property name"};
|
||||||
|
|
||||||
|
// Validate property is settable
|
||||||
|
var readonly = ['size', 'width', 'height'];
|
||||||
|
if (readonly.indexOf(prop) !== -1) {
|
||||||
|
return {error: "Property '" + prop + "' is read-only"};
|
||||||
|
}
|
||||||
|
|
||||||
|
tex[prop] = value;
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'update':
|
||||||
|
if (!msg.data) return {error: "Missing update data"};
|
||||||
|
tex.update(
|
||||||
|
msg.data.rect || null,
|
||||||
|
msg.data.pixels,
|
||||||
|
msg.data.pitch || 0
|
||||||
|
);
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'lock':
|
||||||
|
var result = tex.lock(msg.data ? msg.data.rect : null);
|
||||||
|
return {data: result};
|
||||||
|
|
||||||
|
case 'unlock':
|
||||||
|
tex.unlock();
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
case 'query':
|
||||||
|
return {data: tex.query()};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return {error: "Unknown texture operation: " + msg.op};
|
return {error: "Unknown texture operation: " + msg.op};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Surface operations (mainly for cleanup)
|
||||||
|
function handle_surface(msg) {
|
||||||
|
switch (msg.op) {
|
||||||
|
case 'destroy':
|
||||||
|
if (!msg.id || !resources.surface[msg.id]) {
|
||||||
|
return {error: "Invalid surface id: " + msg.id};
|
||||||
|
}
|
||||||
|
delete resources.surface[msg.id];
|
||||||
|
return {success: true};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return {error: "Unknown surface operation: " + msg.op};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to create window and renderer
|
||||||
|
prosperon.endowments = prosperon.endowments || {};
|
||||||
|
|
||||||
|
// Export resource info for debugging
|
||||||
|
prosperon.sdl_video = {
|
||||||
|
resources: resources,
|
||||||
|
next_id: function() { return next_id; },
|
||||||
|
// Export the actor reference for external access
|
||||||
|
actor: $_
|
||||||
|
};
|
||||||
|
|
||||||
@@ -190,7 +190,6 @@ TO = js2##TYPE(JS, val); \
|
|||||||
JS_FreeValue(JS, val); } \
|
JS_FreeValue(JS, val); } \
|
||||||
|
|
||||||
int js2bool(JSContext *js, JSValue v) { return JS_ToBool(js,v); }
|
int js2bool(JSContext *js, JSValue v) { return JS_ToBool(js,v); }
|
||||||
static inline const char *js2cstring(JSContext *js, JSValue v) { return JS_ToCString(js,v); }
|
|
||||||
|
|
||||||
JSValue number2js(JSContext *js, double g) { return JS_NewFloat64(js,g); }
|
JSValue number2js(JSContext *js, double g) { return JS_NewFloat64(js,g); }
|
||||||
double js2number(JSContext *js, JSValue v) {
|
double js2number(JSContext *js, JSValue v) {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ JSValue js_##ID##_get_##ENTRY (JSContext *js, JSValue self) { \
|
|||||||
return TYPE##2js(js,js2##ID (js, self)->ENTRY); } \
|
return TYPE##2js(js,js2##ID (js, self)->ENTRY); } \
|
||||||
|
|
||||||
#define QJSCLASS(TYPE, ...)\
|
#define QJSCLASS(TYPE, ...)\
|
||||||
static JSClassID js_##TYPE##_id;\
|
JSClassID js_##TYPE##_id;\
|
||||||
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
|
static void js_##TYPE##_finalizer(JSRuntime *rt, JSValue val){\
|
||||||
TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\
|
TYPE *n = JS_GetOpaque(val, js_##TYPE##_id);\
|
||||||
TracyCFreeN(n, #TYPE); \
|
TracyCFreeN(n, #TYPE); \
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,28 @@
|
|||||||
var video = use('sdl_video')
|
var video = use('sdl_video')
|
||||||
|
|
||||||
var myid
|
var window
|
||||||
var myrender
|
var renderer
|
||||||
|
|
||||||
send({__ACTORDATA__:{id:video}}, {kind:"window", op: "create"}, ({id}) => {
|
var act = {__ACTORDATA__:{id:video}}
|
||||||
myid = id
|
|
||||||
|
function handle_response(data)
|
||||||
|
{
|
||||||
|
if (data.error)
|
||||||
|
console.log(json.encode(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
send(act, {kind:"window", op: "create"}, ({id}) => {
|
||||||
|
window = id
|
||||||
console.log(`made window id ${id}`)
|
console.log(`made window id ${id}`)
|
||||||
|
|
||||||
|
send(act, {kind:"window", op:"makeRenderer", id: window}, ({id}) => {
|
||||||
|
renderer = id
|
||||||
|
console.log(`made renderer with id ${id}`)
|
||||||
|
|
||||||
|
send(act, {kind:"renderer", id: renderer, op:"set", prop: "drawColor", value:[0.6,0.4,0.5,1]}, handle_response)
|
||||||
|
send(act, {kind:"renderer", id: renderer, op:"clear"}, handle_response)
|
||||||
|
send(act, {kind:"renderer", id: renderer, op: "present"}, handle_response)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
$_.delay($_.stop, 2)
|
$_.delay($_.stop, 2)
|
||||||
Reference in New Issue
Block a user