remove tracy, mimalloc, enet subprojects; now it's just enet.h

This commit is contained in:
2025-12-07 00:44:02 -06:00
parent 3f2b4177d6
commit ce5949e0ee
12 changed files with 6299 additions and 400 deletions

View File

@@ -68,45 +68,6 @@ if host_machine.system() == 'windows'
add_project_link_arguments('-static-libgcc', '-static-libstdc++', language: ['c', 'cpp'])
endif
if host_machine.system() != 'emscripten' and host_machine.system() != 'playdate'
# Try to find system-installed enet first
enet_dep = dependency('enet', static: true, required: false)
if not enet_dep.found()
message('⚙ System enet not found, building subproject...')
deps += dependency('enet', static:true)
else
deps += enet_dep
endif
mimalloc_enabled = get_option('mimalloc')
if mimalloc_enabled
message('⚙ Using mimalloc subproject for static linking...')
deps += dependency('mimalloc', static:true)
add_project_arguments('-DHAVE_MIMALLOC', language: ['c', 'cpp'])
else
message('⚙ Mimalloc support disabled')
endif
tracy_enabled = get_option('tracy')
if tracy_enabled
message('⚙ Tracy profiling enabled')
tracy_opts = ['fibers=true', 'no_exit=true', 'on_demand=true']
add_project_arguments('-DTRACY_ENABLE', language:['c','cpp'])
# Try to find system-installed tracy first
tracy_dep = dependency('tracy', static: true, required: false)
if not tracy_dep.found()
message('⚙ System tracy not found, building subproject...')
deps += dependency('tracy', static:true, default_options:tracy_opts)
else
deps += tracy_dep
endif
else
message('⚙ Tracy profiling disabled')
endif
endif
#link += '-rdynamic'
link_args = link

View File

@@ -1,7 +0,0 @@
option('editor', type:'boolean', value:true)
option('chipmunk', type:'boolean', value:true)
option('storefront', type:'combo', choices:['none','steam', 'gog', 'egs'], value:'none')
option('qrencode', type:'boolean', value:false)
option('mimalloc', type:'boolean', value:false)
option('tracy', type:'boolean', value:false)
option('single_threaded', type:'boolean', value:false, description:'Use single threaded scheduler')

View File

@@ -1,5 +1,6 @@
#include "cell.h"
#include <enet/enet.h>
#define ENET_IMPLEMENTATION
#include "enet.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
@@ -83,7 +84,7 @@ static JSValue js_enet_host_create(JSContext *ctx, JSValueConst this_val, int ar
if (strcmp(addr_str, "any") == 0)
address.host = ENET_HOST_ANY;
else if (strcmp(addr_str, "broadcast") == 0)
address.host = ENET_HOST_BROADCAST;
enet_address_set_host_ip(&address, "255.255.255.255");
else {
int err = enet_address_set_host_ip(&address, addr_str);
if (err != 0) {
@@ -173,6 +174,9 @@ static JSValue js_enet_host_service(JSContext *ctx, JSValueConst this_val, int a
case ENET_EVENT_TYPE_DISCONNECT:
JS_SetPropertyStr(ctx, event_obj, "type", JS_NewString(ctx, "disconnect"));
break;
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
JS_SetPropertyStr(ctx, event_obj, "type", JS_NewString(ctx, "disconnect_timeout"));
break;
case ENET_EVENT_TYPE_NONE:
JS_SetPropertyStr(ctx, event_obj, "type", JS_NewString(ctx, "none"));
break;
@@ -251,7 +255,7 @@ static JSValue js_enet_host_broadcast(JSContext *ctx, JSValueConst this_val, int
return JS_ThrowTypeError(ctx, "broadcast() only accepts a string or ArrayBuffer");
}
ENetPacket *packet = enet_packet_create(data_str ? data_str : buf, data_len, ENET_PACKET_FLAG_RELIABLE);
ENetPacket *packet = enet_packet_create(data_str ? (const void*)data_str : (const void*)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
if (data_str) JS_FreeCString(ctx, data_str);
if (!packet) return JS_ThrowInternalError(ctx, "Failed to create ENet packet");
@@ -271,15 +275,10 @@ static JSValue js_enet_host_get_address(JSContext *js, JSValueConst self, int ar
ENetHost *me = JS_GetOpaque(self, enet_host_id);
if (!me) return JS_EXCEPTION;
uint32_t host = ntohl(me->address.host);
if (host == 0x7F000001) return JS_NewString(js, "localhost");
char ip_str[16];
snprintf(ip_str, sizeof(ip_str), "%u.%u.%u.%u",
(host >> 24) & 0xFF,
(host >> 16) & 0xFF,
(host >> 8) & 0xFF,
host & 0xFF);
char ip_str[128];
if (enet_address_get_host_ip(&me->address, ip_str, sizeof(ip_str)) != 0)
return JS_NULL;
return JS_NewString(js, ip_str);
}
@@ -321,7 +320,7 @@ static JSValue js_enet_peer_send(JSContext *ctx, JSValueConst this_val, int argc
return JS_ThrowTypeError(ctx, "send() only accepts a string or ArrayBuffer");
}
ENetPacket *packet = enet_packet_create(data_str ? data_str : buf, data_len, ENET_PACKET_FLAG_RELIABLE);
ENetPacket *packet = enet_packet_create(data_str ? (const void*)data_str : (const void*)buf, data_len, ENET_PACKET_FLAG_RELIABLE);
if (data_str) JS_FreeCString(ctx, data_str);
if (!packet) return JS_ThrowInternalError(ctx, "Failed to create ENet packet");
@@ -537,15 +536,10 @@ static JSValue js_enet_peer_get_port(JSContext *js, JSValueConst self)
static JSValue js_enet_peer_get_address(JSContext *js, JSValueConst self)
{
ENetPeer *peer = JS_GetOpaque(self, enet_peer_class_id);
uint32_t host = ntohl(peer->address.host);
if (host == 0x7F000001) return JS_NewString(js, "localhost");
char ip_str[128];
if (enet_address_get_host_ip(&peer->address, ip_str, sizeof(ip_str)) != 0)
return JS_NULL;
char ip_str[16];
snprintf(ip_str, sizeof(ip_str), "%u.%u.%u.%u",
(host >> 24) & 0xFF,
(host >> 16) & 0xFF,
(host >> 8) & 0xFF,
host & 0xFF);
return JS_NewString(js, ip_str);
}

View File

@@ -1,12 +1,3 @@
#ifdef HAVE_MIMALLOC
#include <mimalloc.h>
#endif
#ifdef __APPLE__
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif
@@ -20,180 +11,15 @@
#include "cell.h"
#include "cell_internal.h"
#ifdef TRACY_ENABLE
#include <tracy/TracyC.h>
#endif
#if defined(__APPLE__)
#include <malloc/malloc.h>
#define MALLOC_OVERHEAD 0
#elif defined(_WIN32)
#include <malloc.h>
#define MALLOC_OVERHEAD 8
#elif defined(__linux__) || defined(__GLIBC__)
#define _GNU_SOURCE
#include <malloc.h>
#include <unistd.h>
#define MALLOC_OVERHEAD 8
#else
#define MALLOC_OVERHEAD 0
#endif
#define QOP_IMPLEMENTATION
#include "qop.h"
#define unlikely(x) __builtin_expect(!!(x), 0)
int tracy_profiling_enabled = 0;
#define ENGINE "engine.cm"
static qop_desc qop_core;
static qop_file *qop_hashmap = NULL;
cell_rt *root_cell = NULL;
static size_t js_mi_malloc_usable_size(const void *ptr)
{
#if defined(__APPLE__)
return malloc_size(ptr);
#elif defined(_WIN32)
return _msize((void *)ptr);
#elif defined(EMSCRIPTEN)
return 0;
#elif defined(__linux__) || defined(__GLIBC__)
return malloc_usable_size((void *)ptr);
#else
return malloc_usable_size((void *)ptr);
#endif
}
void *js_mi_malloc(JSMallocState *s, size_t sz) {
void *ptr;
assert(sz != 0);
if (unlikely(s->malloc_size + sz > s->malloc_limit)) return NULL;
#ifdef HAVE_MIMALLOC
cell_rt *actor = (cell_rt*)s->opaque;
ptr = mi_heap_malloc(actor->heap, sz);
#else
ptr = malloc(sz);
#endif
if (!ptr) return NULL;
s->malloc_count++;
s->malloc_size += js_mi_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled) {
#ifdef HAVE_MIMALLOC
cell_rt *actor = (cell_rt*)s->opaque;
TracyCAllocN(ptr, js_mi_malloc_usable_size(ptr) + MALLOC_OVERHEAD, actor->name);
#else
TracyCAllocN(ptr, js_mi_malloc_usable_size(ptr) + MALLOC_OVERHEAD, "actor");
#endif
}
#endif
return ptr;
}
void js_mi_free(JSMallocState *s, void *p) {
if (!p) return;
s->malloc_count--;
s->malloc_size -= js_mi_malloc_usable_size(p) + MALLOC_OVERHEAD;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled) {
#ifdef HAVE_MIMALLOC
cell_rt *actor = s->opaque;
TracyCFreeN(p, actor->name);
#else
TracyCFreeN(p, "actor");
#endif
}
#endif
#ifdef HAVE_MIMALLOC
mi_free(p);
#else
free(p);
#endif
}
void *js_mi_realloc(JSMallocState *s, void *p, size_t sz) {
size_t old_size;
if (!p) return sz ? js_mi_malloc(s, sz) : NULL;
old_size = js_mi_malloc_usable_size(p);
if (!sz) {
s->malloc_count--;
s->malloc_size -= old_size + MALLOC_OVERHEAD;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled) {
#ifdef HAVE_MIMALLOC
cell_rt *actor = (cell_rt*)s->opaque;
TracyCFreeN(p, actor->name);
#else
TracyCFreeN(p, "actor");
#endif
}
#endif
#ifdef HAVE_MIMALLOC
mi_free(p);
#else
free(p);
#endif
return NULL;
}
if (s->malloc_size + sz - old_size > s->malloc_limit) return NULL;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled) {
#ifdef HAVE_MIMALLOC
cell_rt *actor = (cell_rt*)s->opaque;
TracyCFreeN(p, actor->name);
#else
TracyCFreeN(p, "actor");
#endif
}
#endif
#ifdef HAVE_MIMALLOC
cell_rt *actor = (cell_rt*)s->opaque;
p = mi_heap_realloc(actor->heap, p, sz);
#else
p = realloc(p, sz);
#endif
if (!p) return NULL;
s->malloc_size += js_mi_malloc_usable_size(p) - old_size;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled) {
#ifdef HAVE_MIMALLOC
cell_rt *actor = (cell_rt*)s->opaque;
TracyCAllocN(p, js_mi_malloc_usable_size(p) + MALLOC_OVERHEAD, actor->name);
#else
TracyCAllocN(p, js_mi_malloc_usable_size(p) + MALLOC_OVERHEAD, "actor");
#endif
}
#endif
return p;
}
#ifdef HAVE_MIMALLOC
static const JSMallocFunctions mimalloc_funcs = {
js_mi_malloc,
js_mi_free,
js_mi_realloc,
js_mi_malloc_usable_size
};
#endif
int get_executable_path(char *buffer, unsigned int buffer_size) {
#if defined(__linux__)
ssize_t len = readlink("/proc/self/exe", buffer, buffer_size - 1);
@@ -279,67 +105,6 @@ int prosperon_mount_core(void)
return 1;
}
// Wrapper struct to keep the array pointer stable
typedef struct {
#ifdef TRACY_ENABLE
TracyCZoneCtx *arr; // stb_ds dynamic array
#else
void *arr;
#endif
} tracy_stack_t;
#ifdef TRACY_ENABLE
static SDL_TLSID tracy_stack_id = {0};
static void tracy_cleanup_stack(void *value)
{
tracy_stack_t *stack = value;
if (stack) {
arrfree(stack->arr);
free(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)
{
if (!tracy_profiling_enabled)
return;
tracy_stack_t *stack = get_tracy_stack();
js_debug debug;
js_debug_info(js, fn, &debug);
uint64_t srcloc = ___tracy_alloc_srcloc(debug.line, debug.filename, strlen(debug.filename), debug.name, strlen(debug.name), debug.unique);
arrput(stack->arr, ___tracy_emit_zone_begin_alloc(srcloc, 1));
free_js_debug_info(js, &debug);
}
void tracy_end_hook(JSContext *js, JSValue fn)
{
if (!tracy_profiling_enabled)
return;
tracy_stack_t *stack = get_tracy_stack();
if (arrlen(stack->arr) > 0)
___tracy_emit_zone_end(arrpop(stack->arr));
}
#endif
void actor_disrupt(cell_rt *crt)
{
crt->disrupt = 1;
@@ -353,22 +118,11 @@ void script_startup(cell_rt *prt)
{
JSRuntime *rt;
#ifdef HAVE_MIMALLOC
rt = JS_NewRuntime2(&mimalloc_funcs, prt);
#else
rt = JS_NewRuntime();
#endif
JSContext *js = JS_NewContextRaw(rt);
JS_SetInterruptHandler(rt, actor_interrupt_cb, prt);
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled) {
js_debug_sethook(js, tracy_call_hook, JS_HOOK_CALL);
js_debug_sethook(js, tracy_end_hook, JS_HOOK_RET);
}
#endif
JS_AddIntrinsicBaseObjects(js);
JS_AddIntrinsicEval(js);
JS_AddIntrinsicRegExp(js);
@@ -444,7 +198,6 @@ void script_startup(cell_rt *prt)
set_actor_state(crt);
}
#ifndef TARGET_PLAYDATE
static void signal_handler(int sig)
{
const char *str = NULL;
@@ -460,25 +213,11 @@ static void signal_handler(int sig)
exit_handler();
}
#endif
int cell_init(int argc, char **argv)
{
int profile_enabled = 0;
int script_start = 1;
/* Check for --profile flag */
if (argc > 1 && strcmp(argv[1], "--profile") == 0) {
profile_enabled = 1; script_start = 2;
#ifndef TRACY_ENABLE
printf("Warning: --profile flag was specified but Tracy profiling is not compiled in\n");
#endif
}
#ifdef TRACY_ENABLE
tracy_profiling_enabled = profile_enabled;
#endif
/* Load QOP package attached to executable - this is now mandatory! */
int mounted = prosperon_mount_core();
if (!mounted) {
@@ -505,12 +244,10 @@ int cell_init(int argc, char **argv)
root_cell = create_actor(startwota.data);
#ifndef TARGET_PLAYDATE
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGSEGV, signal_handler);
signal(SIGABRT, signal_handler);
#endif
actor_loop();

View File

@@ -1,6 +1,3 @@
#ifdef HAVE_MIMALLOC
typedef struct mi_heap_s mi_heap_t;
#endif
#include <pthread.h>
@@ -27,9 +24,6 @@ typedef struct letter {
typedef struct cell_rt {
JSContext *context;
#ifdef HAVE_MIMALLOC
mi_heap_t *heap;
#endif
JSValue idx_buffer;
JSValue on_exception;
JSValue message_handle;

6257
source/enet.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -148,9 +148,6 @@ void actor_free(cell_rt *actor)
JS_FreeRuntime(rt);
free(actor->id);
#ifdef HAVE_MIMALLOC
mi_heap_destroy(actor->heap);
#endif
free(actor);
int actor_count = shlen(actors);
@@ -330,9 +327,6 @@ void actor_loop()
cell_rt *create_actor(void *wota)
{
cell_rt *actor = calloc(sizeof(*actor), 1);
#ifdef HAVE_MIMALLOC
actor->heap = mi_heap_new();
#endif
actor->init_wota = wota;
actor->idx_buffer = JS_NULL;
actor->message_handle = JS_NULL;
@@ -397,13 +391,6 @@ const char *send_message(const char *id, void *msg)
void actor_turn(cell_rt *actor)
{
#ifdef TRACY_ENABLE
int entered = 0;
if (tracy_profiling_enabled && TracyCIsConnected) {
TracyCFiberEnter(actor->name);
entered = 1;
}
#endif
actor->state = ACTOR_RUNNING;
JSValue result;
@@ -435,10 +422,6 @@ void actor_turn(cell_rt *actor)
ENDTURN:
actor->state = ACTOR_IDLE;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled && entered)
TracyCFiberLeave(actor->name);
#endif
set_actor_state(actor);
}

View File

@@ -303,9 +303,6 @@ void actor_free(cell_rt *actor)
pthread_mutex_destroy(actor->msg_mutex);
free(actor->msg_mutex);
#ifdef HAVE_MIMALLOC
mi_heap_destroy(actor->heap);
#endif
free(actor);
int actor_count = lockless_shlen(actors);
@@ -573,13 +570,6 @@ void actor_turn(cell_rt *actor)
{
pthread_mutex_lock(actor->mutex);
#ifdef TRACY_ENABLE
int entered = 0;
if (tracy_profiling_enabled && TracyCIsConnected) {
TracyCFiberEnter(actor->name);
entered = 1;
}
#endif
actor->state = ACTOR_RUNNING;
@@ -624,10 +614,6 @@ void actor_turn(cell_rt *actor)
ENDTURN:
actor->state = ACTOR_IDLE;
#ifdef TRACY_ENABLE
if (tracy_profiling_enabled && entered)
TracyCFiberLeave(actor->name);
#endif
set_actor_state(actor);

View File

@@ -1,13 +0,0 @@
[wrap-file]
directory = enet-1.3.17
source_url = http://enet.bespin.org/download/enet-1.3.17.tar.gz
source_filename = enet-1.3.17.tar.gz
source_hash = a38f0f194555d558533b8b15c0c478e946310022d0ec7b34334e19e4574dcedc
patch_filename = enet_1.3.17-2_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/enet_1.3.17-2/get_patch
patch_hash = ecafa5c354d3b512c0296121d6be6f39b8a99c286be375f60e94fe097ac401c2
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/enet_1.3.17-2/enet-1.3.17.tar.gz
wrapdb_version = 1.3.17-2
[provide]
enet = enet_dep

View File

@@ -1,13 +0,0 @@
[wrap-file]
directory = mimalloc-3.1.5
source_url = https://github.com/microsoft/mimalloc/archive/refs/tags/v3.1.5.tar.gz
source_filename = mimalloc-3.1.5.tar.gz
source_hash = 1c6949032069d5ebea438ec5cedd602d06f40a92ddf0f0d9dcff0993e5f6635c
patch_filename = mimalloc_3.1.5-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/mimalloc_3.1.5-1/get_patch
patch_hash = 321b4507c1adda5b7aa9954a5f1748e17bf30a11142b4f6c3d52929523565e80
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/mimalloc_3.1.5-1/mimalloc-3.1.5.tar.gz
wrapdb_version = 3.1.5-1
[provide]
mimalloc = mi_dep

View File

@@ -1,7 +0,0 @@
[wrap-git]
url = https://github.com/wolfpld/tracy.git
revision = v0.11.1
depth = 1
[provide]
tracy = tracy_dep

27
todo/playdate.md Normal file
View File

@@ -0,0 +1,27 @@
# Playdate SDK notes
Playdate should compile with playdate.cross
Check for 'pdc' to see if it's available
If it is, use playdate.cross to compile it and everything else
Do not include main; instead, actors should receive messages from the playdate SDK
pdc is used to bundle the compiled game's assets; playdate filesystem only can access files inside that bundle
Simulator dylib is lpatform specific, bundled only to allow it to load into the simulator; doesn't ship to playdate
pdex uses flags from playdate.cross
Example with meson:
pdx = custom_target('pdx bundle',
output: 'GameOfLife.pdx',
command: [join_paths(env['PLAYDATE_SDK_PATH'], 'bin', 'pdc'), 'Source', '@OUTPUT@'],
input: [elf, sim_dylib])
sim_dylib = custom_target('simulator dylib',
output: 'pdex.dylib',
command: ['clang', '-dynamiclib', '-DTARGET_SIMULATOR=1', '-o', '@OUTPUT@', 'main.c', 'setup.c'],
build_by_default: true)
elf = executable('pdex', ['main.c', 'setup.c'],
install: false,
c_args: device_c_args,
link_args: device_link_args)