make tracy work for multilpe contexts
Some checks failed
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
Some checks failed
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
This commit is contained in:
@@ -22,6 +22,13 @@ prosperon.dispatch = function(type, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var os = use_embed('os')
|
var os = use_embed('os')
|
||||||
|
var tracy = use_embed('tracy')
|
||||||
|
|
||||||
|
os.trace = true;
|
||||||
|
|
||||||
|
if (os.trace)
|
||||||
|
tracy.level(1);
|
||||||
|
|
||||||
var js = use_embed('js')
|
var js = use_embed('js')
|
||||||
|
|
||||||
prosperon.on('exit', _ => {
|
prosperon.on('exit', _ => {
|
||||||
@@ -58,7 +65,7 @@ Object.defineProperty(Function.prototype, "hashify", {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var io = use_embed('io')
|
var io = use_embed('io')
|
||||||
var tracy = use_embed('tracy')
|
|
||||||
|
|
||||||
var RESPATH = 'scripts/modules/resources.js'
|
var RESPATH = 'scripts/modules/resources.js'
|
||||||
var canonical = io.realdir(RESPATH) + 'resources.js'
|
var canonical = io.realdir(RESPATH) + 'resources.js'
|
||||||
@@ -285,27 +292,27 @@ var time = use('time')
|
|||||||
|
|
||||||
function parse_file(content, file) {
|
function parse_file(content, file) {
|
||||||
if (!content) return {}
|
if (!content) return {}
|
||||||
var parts = content.split(/\n\s*---\s*\n/)
|
if (!/^\s*---\s*$/m.test(content)) {
|
||||||
if (parts.length === 1) {
|
var part = content.trim()
|
||||||
var part = parts[0]
|
|
||||||
if (part.match(/return\s+[^;]+;?\s*$/))
|
if (part.match(/return\s+[^;]+;?\s*$/))
|
||||||
return { module: part }
|
return { module: part }
|
||||||
return { program: part }
|
return { program: part }
|
||||||
}
|
}
|
||||||
|
var parts = content.split(/\n\s*---\s*\n/)
|
||||||
var module = parts[0]
|
var module = parts[0]
|
||||||
if (!/\breturn\b/.test(module))
|
if (!/\breturn\b/.test(module))
|
||||||
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.`);
|
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new Function(module)()
|
new Function(module)()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.\n` + e.message);
|
throw new Error(`Malformed file: ${file}. Module section must end with a return statement.\n` + e.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
var pad = '\n'.repeat(module.split('\n').length+4)
|
var pad = '\n'.repeat(module.split('\n').length + 4)
|
||||||
return {
|
return {
|
||||||
module,
|
module,
|
||||||
program: pad+parts[1]
|
program: pad + parts[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,8 +762,8 @@ var timers = []
|
|||||||
var timer_id = 0
|
var timer_id = 0
|
||||||
|
|
||||||
$_.delay = function(fn, seconds) {
|
$_.delay = function(fn, seconds) {
|
||||||
timers[timer_id++] = {seconds, fn}
|
var id = os.os.addtimer(prosperon.id, fn, seconds);
|
||||||
return function() { delete timers[timer_id] }
|
return function() { os.removetimer(id); }
|
||||||
}
|
}
|
||||||
$_.delay[prosperon.DOC] = "used to schedule the invocation of a function..."
|
$_.delay[prosperon.DOC] = "used to schedule the invocation of a function..."
|
||||||
|
|
||||||
@@ -836,6 +843,8 @@ cmd.process(prosperon.argv)
|
|||||||
if (!prosperon.args.id) prosperon.id = util.guid()
|
if (!prosperon.args.id) prosperon.id = util.guid()
|
||||||
else prosperon.id = prosperon.args.id
|
else prosperon.id = prosperon.args.id
|
||||||
|
|
||||||
|
tracy.thread_name(prosperon.id)
|
||||||
|
|
||||||
$_.__ACTORDATA__.id = prosperon.id
|
$_.__ACTORDATA__.id = prosperon.id
|
||||||
|
|
||||||
if (prosperon.args.overling) overling = { __ACTORDATA__: {id: prosperon.args.overling} }
|
if (prosperon.args.overling) overling = { __ACTORDATA__: {id: prosperon.args.overling} }
|
||||||
@@ -923,14 +932,14 @@ function handle_message(msg) {
|
|||||||
unneeded_timer = $_.delay(unneeded_fn, unneeded_time)
|
unneeded_timer = $_.delay(unneeded_fn, unneeded_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
var hang = 0.01
|
var hang = 0.1
|
||||||
var last_t = os.now()
|
var last_t = os.now()
|
||||||
|
|
||||||
var doexit = false
|
var doexit = false
|
||||||
while (!doexit) {
|
while (!doexit) {
|
||||||
if (portal) portal.service(handle_host, hang)
|
if (portal) portal.service(handle_host, hang)
|
||||||
if (contactor) contactor.service(handle_host, hang)
|
if (contactor) contactor.service(handle_host, hang)
|
||||||
os.mailbox_service(prosperon.id, handle_local)
|
os.mailbox_service(prosperon.id, handle_local, hang)
|
||||||
var elapsed = os.now() - last_t
|
var elapsed = os.now() - last_t
|
||||||
last_t = os.now()
|
last_t = os.now()
|
||||||
for (var i in timers) {
|
for (var i in timers) {
|
||||||
|
|||||||
153
source/jsffi.c
153
source/jsffi.c
@@ -70,6 +70,7 @@ typedef struct rtree rtree;
|
|||||||
int randombytes(void *buf, size_t n);
|
int randombytes(void *buf, size_t n);
|
||||||
|
|
||||||
static Uint32 timer_cb_event;
|
static Uint32 timer_cb_event;
|
||||||
|
static int trace = 0;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <Accelerate/Accelerate.h>
|
#include <Accelerate/Accelerate.h>
|
||||||
@@ -7093,37 +7094,50 @@ typedef struct {
|
|||||||
int create_new_runtime(cmdargs *data)
|
int create_new_runtime(cmdargs *data)
|
||||||
{
|
{
|
||||||
script_startup(data->argc, data->argv);
|
script_startup(data->argc, data->argv);
|
||||||
|
for (int i = 0; i < data->argc; i++) free(data->argv[i]);
|
||||||
printf("THREAD IS STOPPING\n");
|
free(data->argv);
|
||||||
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_CCALL(os_createthread,
|
JSC_CCALL(os_createthread,
|
||||||
cmdargs cmd;
|
cmdargs *cmd = malloc(sizeof(cmdargs));
|
||||||
cmd.argc = JS_ArrayLength(js,argv[0]);
|
if (!cmd) return JS_ThrowInternalError(js, "Out of memory");
|
||||||
cmd.argv = (char **)calloc(cmd.argc, sizeof(char *));
|
cmd->argc = JS_ArrayLength(js, argv[0]);
|
||||||
// Convert JS array elements to C strings
|
cmd->argv = (char **)calloc(cmd->argc, sizeof(char *));
|
||||||
for (int i = 0; i < cmd.argc; i++) {
|
if (!cmd->argv) {
|
||||||
JSValue val = JS_GetPropertyUint32(js, argv[0], i);
|
free(cmd);
|
||||||
if (JS_IsException(val)) {
|
return JS_ThrowInternalError(js, "Out of memory");
|
||||||
free(cmd.argv);
|
}
|
||||||
return val;
|
for (int i = 0; i < cmd->argc; i++) {
|
||||||
}
|
JSValue val = JS_GetPropertyUint32(js, argv[0], i);
|
||||||
|
if (JS_IsException(val)) {
|
||||||
const char *str = JS_ToCString(js, val);
|
for (int j = 0; j < i; j++) free(cmd->argv[j]);
|
||||||
if (!str) {
|
free(cmd->argv);
|
||||||
free(cmd.argv);
|
free(cmd);
|
||||||
JS_FreeValue(js, val);
|
return val;
|
||||||
return JS_ThrowInternalError(js, "Could not convert argument to string");
|
}
|
||||||
}
|
const char *str = JS_ToCString(js, val);
|
||||||
|
if (!str) {
|
||||||
cmd.argv[i] = strdup(str); // Make a copy of the string
|
for (int j = 0; j < i; j++) free(cmd->argv[j]);
|
||||||
JS_FreeCString(js, str);
|
free(cmd->argv);
|
||||||
JS_FreeValue(js, val);
|
free(cmd);
|
||||||
|
JS_FreeValue(js, val);
|
||||||
|
return JS_ThrowInternalError(js, "Could not convert argument to string");
|
||||||
|
}
|
||||||
|
cmd->argv[i] = strdup(str);
|
||||||
|
JS_FreeCString(js, str);
|
||||||
|
JS_FreeValue(js, val);
|
||||||
|
}
|
||||||
|
SDL_Thread *thread = SDL_CreateThread(create_new_runtime, "newrt", cmd);
|
||||||
|
if (!thread) {
|
||||||
|
for (int i = 0; i < cmd->argc; i++) free(cmd->argv[i]);
|
||||||
|
free(cmd->argv);
|
||||||
|
free(cmd);
|
||||||
|
return JS_ThrowInternalError(js, "Could not create a new thread: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
SDL_Thread *thread = SDL_CreateThread(create_new_runtime, "newrt", &cmd);
|
|
||||||
if (!thread) return JS_ThrowInternalError(js, "Could not create a new thread: %s", SDL_GetError());
|
|
||||||
SDL_DetachThread(thread);
|
SDL_DetachThread(thread);
|
||||||
|
return JS_UNDEFINED;
|
||||||
)
|
)
|
||||||
|
|
||||||
struct message {
|
struct message {
|
||||||
@@ -7133,6 +7147,7 @@ struct message {
|
|||||||
|
|
||||||
typedef struct mailbox {
|
typedef struct mailbox {
|
||||||
SDL_Mutex *mutex;
|
SDL_Mutex *mutex;
|
||||||
|
SDL_Condition *cond;
|
||||||
struct message *messages;
|
struct message *messages;
|
||||||
} mailbox;
|
} mailbox;
|
||||||
|
|
||||||
@@ -7141,29 +7156,28 @@ static SDL_Mutex *mailboxes_mutex = NULL;
|
|||||||
|
|
||||||
JSC_CCALL(os_mailbox_push,
|
JSC_CCALL(os_mailbox_push,
|
||||||
if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and a message");
|
if (argc < 2) return JS_ThrowInternalError(js, "Need an actor and a message");
|
||||||
if (!JS_IsArrayBuffer(js, argv[1])) return JS_ThrowInternalError(js, "Object to push into the mailbox must be an array buffer.");
|
if (!JS_IsArrayBuffer(js, argv[1])) return JS_ThrowInternalError(js, "Object to push must be an array buffer");
|
||||||
|
|
||||||
const char *id = JS_ToCString(js, argv[0]);
|
const char *id = JS_ToCString(js, argv[0]);
|
||||||
int mailbox_index = shgeti(mailboxes, id);
|
int mailbox_index = shgeti(mailboxes, id);
|
||||||
JS_FreeCString(js, id);
|
JS_FreeCString(js, id);
|
||||||
|
|
||||||
if (mailbox_index == -1)
|
if (mailbox_index == -1) return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||||
return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
uint8_t *buf = JS_GetArrayBuffer(js, &size, argv[1]);
|
uint8_t *buf = JS_GetArrayBuffer(js, &size, argv[1]);
|
||||||
|
if (!buf) return JS_ThrowInternalError(js, "Could not get data from arraybuffer");
|
||||||
if (!buf) return JS_ThrowInternalError(js, "Could not get data from arraybuffer.");
|
|
||||||
|
|
||||||
void *data = js_malloc_rt(JS_GetRuntime(js), size);
|
void *data = js_malloc_rt(JS_GetRuntime(js), size);
|
||||||
if (!data) return JS_ThrowInternalError(js, "Memory allocation failed.");
|
if (!data) return JS_ThrowInternalError(js, "Memory allocation failed");
|
||||||
|
|
||||||
memcpy(data,buf,size);
|
memcpy(data, buf, size);
|
||||||
|
|
||||||
mailbox *mb = &mailboxes[mailbox_index].value;
|
mailbox *mb = &mailboxes[mailbox_index].value;
|
||||||
SDL_LockMutex(mb->mutex);
|
SDL_LockMutex(mb->mutex);
|
||||||
struct message msg = {data, size};
|
struct message msg = {data, size};
|
||||||
arrput(mb->messages, msg);
|
arrput(mb->messages, msg);
|
||||||
|
SDL_SignalCondition(mb->cond); // Signal waiting threads
|
||||||
SDL_UnlockMutex(mb->mutex);
|
SDL_UnlockMutex(mb->mutex);
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -7174,6 +7188,7 @@ void js_dofree(JSRuntime *rt, void *opaque, void *ptr)
|
|||||||
|
|
||||||
JSC_CCALL(os_mailbox_service,
|
JSC_CCALL(os_mailbox_service,
|
||||||
if (!JS_IsFunction(js, argv[1])) return JS_ThrowInternalError(js, "Arg 2 must be a function");
|
if (!JS_IsFunction(js, argv[1])) return JS_ThrowInternalError(js, "Arg 2 must be a function");
|
||||||
|
if (argc < 3 || !JS_IsNumber(argv[2])) return JS_ThrowInternalError(js, "Arg 3 must be a number (timeout in seconds)");
|
||||||
|
|
||||||
const char *id = JS_ToCString(js, argv[0]);
|
const char *id = JS_ToCString(js, argv[0]);
|
||||||
int mb_index = shgeti(mailboxes, id);
|
int mb_index = shgeti(mailboxes, id);
|
||||||
@@ -7181,9 +7196,25 @@ JSC_CCALL(os_mailbox_service,
|
|||||||
|
|
||||||
if (mb_index == -1) return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
if (mb_index == -1) return JS_ThrowInternalError(js, "No mailbox found for given ID");
|
||||||
|
|
||||||
|
// Get timeout in seconds and convert to milliseconds
|
||||||
|
int32_t timeout_seconds;
|
||||||
|
if (JS_ToInt32(js, &timeout_seconds, argv[2]) != 0) return JS_ThrowInternalError(js, "Invalid timeout value");
|
||||||
|
int timeout_ms = timeout_seconds * 1000; // Convert to milliseconds for SDL
|
||||||
|
|
||||||
mailbox *mb = &mailboxes[mb_index].value;
|
mailbox *mb = &mailboxes[mb_index].value;
|
||||||
struct message *temp = NULL;
|
struct message *temp = NULL;
|
||||||
SDL_LockMutex(mb->mutex);
|
SDL_LockMutex(mb->mutex);
|
||||||
|
|
||||||
|
// Wait for messages if the mailbox is empty
|
||||||
|
while (arrlen(mb->messages) == 0) {
|
||||||
|
bool signaled = SDL_WaitConditionTimeout(mb->cond, mb->mutex, timeout_ms);
|
||||||
|
if (!signaled) { // Timeout occurred
|
||||||
|
SDL_UnlockMutex(mb->mutex);
|
||||||
|
return JS_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process messages after wait
|
||||||
int count = arrlen(mb->messages);
|
int count = arrlen(mb->messages);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
arrsetlen(temp, count);
|
arrsetlen(temp, count);
|
||||||
@@ -7200,7 +7231,7 @@ JSC_CCALL(os_mailbox_service,
|
|||||||
JSValue arg = JS_NewArrayBuffer(js, temp[i].data, temp[i].size, js_dofree, NULL, 0);
|
JSValue arg = JS_NewArrayBuffer(js, temp[i].data, temp[i].size, js_dofree, NULL, 0);
|
||||||
JSValue call = JS_Call(js, fn, JS_UNDEFINED, 1, &arg);
|
JSValue call = JS_Call(js, fn, JS_UNDEFINED, 1, &arg);
|
||||||
uncaught_exception(js, call);
|
uncaught_exception(js, call);
|
||||||
JS_FreeValue(js,arg);
|
JS_FreeValue(js, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
arrfree(temp);
|
arrfree(temp);
|
||||||
@@ -7218,6 +7249,7 @@ JSC_CCALL(os_mailbox_start,
|
|||||||
const char *id = JS_ToCString(js, argv[0]);
|
const char *id = JS_ToCString(js, argv[0]);
|
||||||
mailbox mb;
|
mailbox mb;
|
||||||
mb.mutex = SDL_CreateMutex();
|
mb.mutex = SDL_CreateMutex();
|
||||||
|
mb.cond = SDL_CreateCondition();
|
||||||
mb.messages = NULL;
|
mb.messages = NULL;
|
||||||
if (!mailboxes_mutex) mailboxes_mutex = SDL_CreateMutex();
|
if (!mailboxes_mutex) mailboxes_mutex = SDL_CreateMutex();
|
||||||
|
|
||||||
@@ -7245,6 +7277,7 @@ JSC_CCALL(os_mailbox_destroy,
|
|||||||
SDL_UnlockMutex(mb->mutex);
|
SDL_UnlockMutex(mb->mutex);
|
||||||
|
|
||||||
SDL_DestroyMutex(mb->mutex);
|
SDL_DestroyMutex(mb->mutex);
|
||||||
|
SDL_DestroyCondition(mb->cond);
|
||||||
|
|
||||||
SDL_LockMutex(mailboxes_mutex);
|
SDL_LockMutex(mailboxes_mutex);
|
||||||
shdel(mailboxes, id);
|
shdel(mailboxes, id);
|
||||||
@@ -7273,16 +7306,68 @@ JSC_CCALL(os_waitevent,
|
|||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
JSValue js_os_get_trace(JSContext *js, JSValue self)
|
||||||
|
{
|
||||||
|
return JS_NewBool(js, trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSValue js_os_set_trace(JSContext *js, JSValue self, JSValue value)
|
||||||
|
{
|
||||||
|
trace = JS_ToBool(js, value);
|
||||||
|
return JS_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *timer_id; // Unique timer identifier
|
||||||
|
char *mailbox_id; // Mailbox to send the message to
|
||||||
|
} timer_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *timer_id; // Timer ID
|
||||||
|
JSValue fn; // Function to invoke
|
||||||
|
} timer_mapping;
|
||||||
|
|
||||||
|
static timer_mapping *timers = NULL; // Dynamic array of timer mappings
|
||||||
|
static SDL_Mutex *timers_mutex = NULL; // Mutex for thread-safe access to timers
|
||||||
|
|
||||||
|
void init_timers(void)
|
||||||
|
{
|
||||||
|
if (!timers_mutex) timers_mutex = SDL_CreateMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
JSValue fn;
|
||||||
|
const char *id;
|
||||||
|
} timer_cb;
|
||||||
|
|
||||||
|
JSC_CCALL(os_addtimer,
|
||||||
|
|
||||||
|
Uint64 ns = js2number(js,argv[1])*1000000000.0;
|
||||||
|
timer_cb cb;
|
||||||
|
cb.fn = JS_DupValue(js,argv[0]);
|
||||||
|
cb.id = JS_ToCString(js,argv[2]);
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(os_removetimer,
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_os_funcs[] = {
|
static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
MIST_FUNC_DEF(os, make_transform, 0),
|
MIST_FUNC_DEF(os, make_transform, 0),
|
||||||
MIST_FUNC_DEF(os, clean_transforms, 0),
|
MIST_FUNC_DEF(os, clean_transforms, 0),
|
||||||
|
|
||||||
|
MIST_FUNC_DEF(os, addtimer, 3),
|
||||||
|
MIST_FUNC_DEF(os, removetimer, 1),
|
||||||
|
|
||||||
MIST_FUNC_DEF(os, platform, 0),
|
MIST_FUNC_DEF(os, platform, 0),
|
||||||
MIST_FUNC_DEF(os, arch, 0),
|
MIST_FUNC_DEF(os, arch, 0),
|
||||||
MIST_FUNC_DEF(os, totalmem, 0),
|
MIST_FUNC_DEF(os, totalmem, 0),
|
||||||
MIST_FUNC_DEF(os, freemem, 0),
|
MIST_FUNC_DEF(os, freemem, 0),
|
||||||
MIST_FUNC_DEF(os, hostname, 0),
|
MIST_FUNC_DEF(os, hostname, 0),
|
||||||
MIST_FUNC_DEF(os, version, 0),
|
MIST_FUNC_DEF(os, version, 0),
|
||||||
|
JS_CGETSET_DEF("trace", js_os_get_trace, js_os_set_trace),
|
||||||
|
|
||||||
MIST_FUNC_DEF(os, kill, 1),
|
MIST_FUNC_DEF(os, kill, 1),
|
||||||
MIST_FUNC_DEF(os, exit, 1),
|
MIST_FUNC_DEF(os, exit, 1),
|
||||||
@@ -8005,8 +8090,6 @@ void ffi_load(JSContext *js, int argc, char **argv) {
|
|||||||
QJSCLASSPREP_FUNCS(datastream);
|
QJSCLASSPREP_FUNCS(datastream);
|
||||||
QJSCLASSPREP_FUNCS(timer);
|
QJSCLASSPREP_FUNCS(timer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
timer_cb_event = SDL_RegisterEvents(1);
|
timer_cb_event = SDL_RegisterEvents(1);
|
||||||
|
|
||||||
JS_SetPropertyStr(js, globalThis, "use_dyn", JS_NewCFunction(js,js_os_use_dyn,"use_dyn", 1));
|
JS_SetPropertyStr(js, globalThis, "use_dyn", JS_NewCFunction(js,js_os_use_dyn,"use_dyn", 1));
|
||||||
|
|||||||
@@ -109,6 +109,5 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
script_startup(argc, argv); // runs engine.js
|
script_startup(argc, argv); // runs engine.js
|
||||||
printf("MADE IT HERE AT BOTTOM OF MAIN\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,26 +496,57 @@ static JSValue js_tracy_image(JSContext *js, JSValue self, int argc, JSValue *ar
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static TracyCZoneCtx *tracy_stack;
|
// Wrapper struct to keep the array pointer stable
|
||||||
|
typedef struct {
|
||||||
|
TracyCZoneCtx *arr; // stb_ds dynamic array
|
||||||
|
} tracy_stack_t;
|
||||||
|
|
||||||
|
// Global TLS ID for the Tracy stack
|
||||||
|
static SDL_TLSID tracy_stack_id = {0};
|
||||||
|
|
||||||
|
// Cleanup function for the wrapper struct
|
||||||
|
static void tracy_cleanup_stack(void *value)
|
||||||
|
{
|
||||||
|
tracy_stack_t *stack = value;
|
||||||
|
if (stack) {
|
||||||
|
arrfree(stack->arr);
|
||||||
|
free(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get or initialize the thread-local Tracy stack
|
||||||
|
static tracy_stack_t *get_tracy_stack(void)
|
||||||
|
{
|
||||||
|
tracy_stack_t *stack = SDL_GetTLS(&tracy_stack_id);
|
||||||
|
if (!stack) {
|
||||||
|
stack = malloc(sizeof(tracy_stack_t));
|
||||||
|
stack->arr = NULL; // stb_ds starts with NULL
|
||||||
|
arrsetcap(stack->arr, 5); // Initial capacity
|
||||||
|
SDL_SetTLS(&tracy_stack_id, stack, tracy_cleanup_stack);
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
void tracy_call_hook(JSContext *js, JSValue fn)
|
void tracy_call_hook(JSContext *js, JSValue fn)
|
||||||
{
|
{
|
||||||
|
tracy_stack_t *stack = get_tracy_stack();
|
||||||
js_debug debug;
|
js_debug debug;
|
||||||
js_debug_info(js,fn,&debug);
|
js_debug_info(js, fn, &debug);
|
||||||
|
|
||||||
uint64_t srcloc;
|
uint64_t srcloc = ___tracy_alloc_srcloc(debug.line, debug.filename, strlen(debug.filename), debug.name, strlen(debug.name), debug.unique);
|
||||||
srcloc = ___tracy_alloc_srcloc(debug.line, debug.source, debug.srclen, debug.name, strlen(debug.name), (int)debug.source);
|
arrput(stack->arr, ___tracy_emit_zone_begin_alloc(srcloc, 1));
|
||||||
|
|
||||||
arrput(tracy_stack, ___tracy_emit_zone_begin_alloc(srcloc,1));
|
free_js_debug_info(js, &debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tracy_end_hook(JSContext *js, JSValue fn)
|
void tracy_end_hook(JSContext *js, JSValue fn)
|
||||||
{
|
{
|
||||||
if (arrlen(tracy_stack) >0)
|
tracy_stack_t *stack = get_tracy_stack();
|
||||||
___tracy_emit_zone_end(arrpop(tracy_stack));
|
if (arrlen(stack->arr) > 0)
|
||||||
|
___tracy_emit_zone_end(arrpop(stack->arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue js_tracy_level(JSContext *js, JSValue selff, int argc, JSValue *argv)
|
JSValue js_tracy_level(JSContext *js, JSValue self, int argc, JSValue *argv)
|
||||||
{
|
{
|
||||||
int32_t level;
|
int32_t level;
|
||||||
JS_ToInt32(js,&level, argv[0]);
|
JS_ToInt32(js,&level, argv[0]);
|
||||||
|
|||||||
@@ -188,7 +188,6 @@ void script_stop(JSContext *js)
|
|||||||
|
|
||||||
free(prt);
|
free(prt);
|
||||||
|
|
||||||
printf("STOPPING CONTEXT %p\n", js);
|
|
||||||
JSValue *onexp = SDL_GetTLS(&on_exception);
|
JSValue *onexp = SDL_GetTLS(&on_exception);
|
||||||
JS_FreeValue(js,*onexp);
|
JS_FreeValue(js,*onexp);
|
||||||
JSRuntime *rt = JS_GetRuntime(js);
|
JSRuntime *rt = JS_GetRuntime(js);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
var os = use('os')
|
var os = use('os')
|
||||||
|
|
||||||
$_.stop()
|
|
||||||
|
|
||||||
$_.start(e => {
|
$_.start(e => {
|
||||||
switch(e.type) {
|
switch(e.type) {
|
||||||
case "actor_started":
|
case "actor_started":
|
||||||
@@ -13,6 +11,5 @@ $_.start(e => {
|
|||||||
$_.couple(e.actor)
|
$_.couple(e.actor)
|
||||||
|
|
||||||
$_.stop(e.actor)
|
$_.stop(e.actor)
|
||||||
$_.stop()
|
|
||||||
}
|
}
|
||||||
}, "tests/underling.js");
|
}, "tests/underling.js");
|
||||||
|
|||||||
Reference in New Issue
Block a user