update
This commit is contained in:
@@ -53,6 +53,11 @@ const libraries = [
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const benchmarks = [
|
const benchmarks = [
|
||||||
|
{
|
||||||
|
name: "Empty object",
|
||||||
|
data: [{}, {}, {}, {}],
|
||||||
|
iterations: 10000
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Small Integers",
|
name: "Small Integers",
|
||||||
data: [0, 42, -1, 2023],
|
data: [0, 42, -1, 2023],
|
||||||
@@ -125,8 +130,8 @@ function runBenchmarkForLibrary(lib, bench) {
|
|||||||
let encodeTime = measureTime(() => {
|
let encodeTime = measureTime(() => {
|
||||||
for (let i = 0; i < bench.iterations; i++) {
|
for (let i = 0; i < bench.iterations; i++) {
|
||||||
// For each data item, encode it
|
// For each data item, encode it
|
||||||
for (let d of bench.data) {
|
for (let j = 0; j < bench.data.length; j++) {
|
||||||
let e = lib.encode(d);
|
let e = lib.encode(bench.data[j]);
|
||||||
// store only in the very first iteration, so we can decode them later
|
// store only in the very first iteration, so we can decode them later
|
||||||
// but do not store them every iteration or we blow up memory.
|
// but do not store them every iteration or we blow up memory.
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
@@ -171,8 +176,8 @@ for (let bench of benchmarks) {
|
|||||||
let decOpsPerSec = (totalOps / decodeTime).toFixed(1);
|
let decOpsPerSec = (totalOps / decodeTime).toFixed(1);
|
||||||
|
|
||||||
console.log(` ${lib.name}:`);
|
console.log(` ${lib.name}:`);
|
||||||
console.log(` Encode time: ${encodeTime.toFixed(3)}s => ${encOpsPerSec} encodes/sec`);
|
console.log(` Encode time: ${encodeTime.toFixed(3)}s => ${encOpsPerSec} encodes/sec [${(encodeTime/bench.iterations)*1000000000} ns/try]`);
|
||||||
console.log(` Decode time: ${decodeTime.toFixed(3)}s => ${decOpsPerSec} decodes/sec`);
|
console.log(` Decode time: ${decodeTime.toFixed(3)}s => ${decOpsPerSec} decodes/sec [${(decodeTime/bench.iterations)*1000000000}/try]`);
|
||||||
console.log(` Total size: ${totalSize} bytes (or code units for JSON)`);
|
console.log(` Total size: ${totalSize} bytes (or code units for JSON)`);
|
||||||
console.log("");
|
console.log("");
|
||||||
}
|
}
|
||||||
@@ -180,3 +185,5 @@ for (let bench of benchmarks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log("Benchmark complete.\n");
|
console.log("Benchmark complete.\n");
|
||||||
|
|
||||||
|
os.exit()
|
||||||
|
|||||||
@@ -353,8 +353,8 @@ function handle_renderer(msg) {
|
|||||||
if (!tex_id || !resources.texture[tex_id]) return {error: "Invalid texture id"};
|
if (!tex_id || !resources.texture[tex_id]) return {error: "Invalid texture id"};
|
||||||
ren.texture(
|
ren.texture(
|
||||||
resources.texture[tex_id],
|
resources.texture[tex_id],
|
||||||
msg.data.src || {x:0, y:0, w:1, h:1},
|
msg.data.src,
|
||||||
msg.data.dst || {x:0, y:0, w:100, h:100},
|
msg.data.dst,
|
||||||
msg.data.angle || 0,
|
msg.data.angle || 0,
|
||||||
msg.data.anchor || {x:0.5, y:0.5}
|
msg.data.anchor || {x:0.5, y:0.5}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -183,15 +183,6 @@ draw.slice9 = function slice9(image, rect = [0,0], slice = 0, info = slice9_info
|
|||||||
material: material
|
material: material
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
draw.slice9[prosperon.DOC] = `
|
|
||||||
:param image: An image object or string path to a texture.
|
|
||||||
:param rect: A rectangle specifying draw location/size, default [0, 0].
|
|
||||||
:param slice: The pixel inset or spacing for the 9-slice (number or object).
|
|
||||||
:param info: A slice9 info object controlling tiling of edges/corners.
|
|
||||||
:param material: Material/styling information
|
|
||||||
:return: None
|
|
||||||
:raises Error: If no image is provided.
|
|
||||||
`
|
|
||||||
|
|
||||||
draw.image = function image(image, rect = [0,0], rotation = 0, anchor = [0,0], shear = [0,0], info = {}, material) {
|
draw.image = function image(image, rect = [0,0], rotation = 0, anchor = [0,0], shear = [0,0], info = {}, material) {
|
||||||
if (!image) throw Error('Need an image to render.')
|
if (!image) throw Error('Need an image to render.')
|
||||||
@@ -228,15 +219,5 @@ draw.text = function text(text, rect, font = 'fonts/c64.ttf', size = 8, color =
|
|||||||
material: {color}
|
material: {color}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
draw.text[prosperon.DOC] = `
|
|
||||||
:param text: The string to draw.
|
|
||||||
:param rect: A rectangle specifying draw position (and possibly wrapping area).
|
|
||||||
:param font: A font object or string path, default sysfont.
|
|
||||||
:param size: Font size in pixels.
|
|
||||||
:param color: The text color, default color.white.
|
|
||||||
:param wrap: Pixel width for text wrapping, default 0 (no wrap).
|
|
||||||
:param material: Material/styling information
|
|
||||||
:return: None
|
|
||||||
`
|
|
||||||
|
|
||||||
return draw
|
return draw
|
||||||
@@ -159,11 +159,8 @@ function create_image(path){
|
|||||||
let raw = decode_image(bytes, path.ext());
|
let raw = decode_image(bytes, path.ext());
|
||||||
|
|
||||||
/* ── Case A: static image ─────────────────────────────────── */
|
/* ── Case A: static image ─────────────────────────────────── */
|
||||||
if(raw.surface) {
|
if(raw.surface)
|
||||||
console.log("STATIC!")
|
|
||||||
console.log(json.encode(raw.surface))
|
|
||||||
return make_handle(raw.surface);
|
return make_handle(raw.surface);
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Case B: GIF helpers returned array [surf, …] ─────────── */
|
/* ── Case B: GIF helpers returned array [surf, …] ─────────── */
|
||||||
if(Array.isArray(raw))
|
if(Array.isArray(raw))
|
||||||
|
|||||||
@@ -1569,6 +1569,9 @@ void ffi_load(JSContext *js)
|
|||||||
arrput(rt->module_registry, MISTLINE(sprite));
|
arrput(rt->module_registry, MISTLINE(sprite));
|
||||||
arrput(rt->module_registry, MISTLINE(transform));
|
arrput(rt->module_registry, MISTLINE(transform));
|
||||||
|
|
||||||
|
arrput(rt->module_registry, MISTLINE(wota));
|
||||||
|
arrput(rt->module_registry, MISTLINE(nota));
|
||||||
|
|
||||||
#ifndef NSTEAM
|
#ifndef NSTEAM
|
||||||
arrput(rt->module_registry, MISTLINE(steam));
|
arrput(rt->module_registry, MISTLINE(steam));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int tracy_profiling_enabled = 0;
|
||||||
|
|
||||||
#define ENGINE "scripts/core/engine.js"
|
#define ENGINE "scripts/core/engine.js"
|
||||||
|
|
||||||
static prosperon_rt **ready_queue = NULL;
|
static prosperon_rt **ready_queue = NULL;
|
||||||
@@ -331,7 +333,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
|
|||||||
{
|
{
|
||||||
SDL_LockMutex(actor->turn);
|
SDL_LockMutex(actor->turn);
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
TracyCFiberEnter(actor->name);
|
if (tracy_profiling_enabled)
|
||||||
|
TracyCFiberEnter(actor->name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_LockMutex(actor->msg_mutex);
|
SDL_LockMutex(actor->msg_mutex);
|
||||||
@@ -420,7 +423,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
|
|||||||
|
|
||||||
END:
|
END:
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
TracyCFiberLeave(actor->name);
|
if (tracy_profiling_enabled)
|
||||||
|
TracyCFiberLeave(actor->name);
|
||||||
#endif
|
#endif
|
||||||
SDL_UnlockMutex(actor->turn);
|
SDL_UnlockMutex(actor->turn);
|
||||||
set_actor_state(actor);
|
set_actor_state(actor);
|
||||||
@@ -428,7 +432,8 @@ void actor_turn(prosperon_rt *actor, int greedy)
|
|||||||
|
|
||||||
KILL:
|
KILL:
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
TracyCFiberLeave(actor->id);
|
if (tracy_profiling_enabled)
|
||||||
|
TracyCFiberLeave(actor->name);
|
||||||
#endif
|
#endif
|
||||||
SDL_UnlockMutex(actor->turn);
|
SDL_UnlockMutex(actor->turn);
|
||||||
actor_free(actor);
|
actor_free(actor);
|
||||||
@@ -614,6 +619,9 @@ static tracy_stack_t *get_tracy_stack(void)
|
|||||||
|
|
||||||
void tracy_call_hook(JSContext *js, JSValue fn)
|
void tracy_call_hook(JSContext *js, JSValue fn)
|
||||||
{
|
{
|
||||||
|
if (!tracy_profiling_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
tracy_stack_t *stack = get_tracy_stack();
|
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);
|
||||||
@@ -626,6 +634,9 @@ void tracy_call_hook(JSContext *js, JSValue fn)
|
|||||||
|
|
||||||
void tracy_end_hook(JSContext *js, JSValue fn)
|
void tracy_end_hook(JSContext *js, JSValue fn)
|
||||||
{
|
{
|
||||||
|
if (!tracy_profiling_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
tracy_stack_t *stack = get_tracy_stack();
|
tracy_stack_t *stack = get_tracy_stack();
|
||||||
if (arrlen(stack->arr) > 0)
|
if (arrlen(stack->arr) > 0)
|
||||||
___tracy_emit_zone_end(arrpop(stack->arr));
|
___tracy_emit_zone_end(arrpop(stack->arr));
|
||||||
@@ -635,15 +646,20 @@ void script_startup(prosperon_rt *prt, void (*hook)(JSContext*))
|
|||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
rt = JS_NewRuntime2(&tracy_malloc_funcs, NULL);
|
if (tracy_profiling_enabled)
|
||||||
|
rt = JS_NewRuntime2(&tracy_malloc_funcs, NULL);
|
||||||
|
else
|
||||||
|
rt = JS_NewRuntime();
|
||||||
#else
|
#else
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
#endif
|
#endif
|
||||||
JSContext *js = JS_NewContextRaw(rt);
|
JSContext *js = JS_NewContextRaw(rt);
|
||||||
|
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
js_debug_sethook(js, tracy_call_hook, JS_HOOK_CALL);
|
if (tracy_profiling_enabled) {
|
||||||
js_debug_sethook(js, tracy_end_hook, JS_HOOK_RET);
|
js_debug_sethook(js, tracy_call_hook, JS_HOOK_CALL);
|
||||||
|
js_debug_sethook(js, tracy_end_hook, JS_HOOK_RET);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JS_AddIntrinsicBaseObjects(js);
|
JS_AddIntrinsicBaseObjects(js);
|
||||||
@@ -1455,7 +1471,17 @@ bool event_watch(void *data, SDL_Event *e)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *new_cwd = NULL;
|
const char *new_cwd = NULL;
|
||||||
for (int i = 1; i < argc; i++) {
|
int profile_enabled = 0;
|
||||||
|
int script_start = 1;
|
||||||
|
|
||||||
|
// Check for --profile flag first
|
||||||
|
if (argc > 1 && strcmp(argv[1], "--profile") == 0) {
|
||||||
|
profile_enabled = 1;
|
||||||
|
script_start = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for --cwd flag
|
||||||
|
for (int i = script_start; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "--cwd") == 0) {
|
if (strcmp(argv[i], "--cwd") == 0) {
|
||||||
i++;
|
i++;
|
||||||
if (i < argc) new_cwd = argv[i];
|
if (i < argc) new_cwd = argv[i];
|
||||||
@@ -1469,6 +1495,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
queue_event = SDL_RegisterEvents(1);
|
queue_event = SDL_RegisterEvents(1);
|
||||||
|
|
||||||
|
#ifdef TRACY_ENABLE
|
||||||
|
tracy_profiling_enabled = profile_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
main_thread = SDL_GetCurrentThreadID();
|
main_thread = SDL_GetCurrentThreadID();
|
||||||
|
|
||||||
int cores = SDL_GetNumLogicalCPUCores();
|
int cores = SDL_GetNumLogicalCPUCores();
|
||||||
@@ -1495,7 +1525,11 @@ int main(int argc, char **argv)
|
|||||||
event_watchers_mutex = SDL_CreateMutex();
|
event_watchers_mutex = SDL_CreateMutex();
|
||||||
|
|
||||||
/* Create the initial actor from the main command line. */
|
/* Create the initial actor from the main command line. */
|
||||||
create_actor(argc, argv, NULL);
|
/* Adjust argc and argv to skip --profile if present */
|
||||||
|
int actor_argc = argc - (script_start - 1);
|
||||||
|
char **actor_argv = argv + (script_start - 1);
|
||||||
|
actor_argv[0] = argv[0]; // Keep the program name
|
||||||
|
create_actor(actor_argc, actor_argv, NULL);
|
||||||
|
|
||||||
cores = 1;
|
cores = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -97,9 +97,9 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
|
|||||||
int tag = JS_VALUE_GET_TAG(replaced);
|
int tag = JS_VALUE_GET_TAG(replaced);
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case JS_TAG_INT: {
|
case JS_TAG_INT: {
|
||||||
double d;
|
int32_t d;
|
||||||
JS_ToFloat64(ctx, &d, replaced);
|
JS_ToInt32(ctx, &d, replaced);
|
||||||
wota_write_number(&enc->wb, d);
|
wota_write_int_word(&enc->wb, d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JS_TAG_FLOAT64:
|
case JS_TAG_FLOAT64:
|
||||||
@@ -109,7 +109,7 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
|
|||||||
wota_write_sym(&enc->wb, WOTA_NULL);
|
wota_write_sym(&enc->wb, WOTA_NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wota_write_number(&enc->wb, d);
|
wota_write_float_word(&enc->wb, d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JS_TAG_STRING: {
|
case JS_TAG_STRING: {
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ void wota_write_record (WotaBuffer *wb, unsigned long long count);
|
|||||||
void wota_write_number (WotaBuffer *wb, double n);
|
void wota_write_number (WotaBuffer *wb, double n);
|
||||||
/* Symbol codes (WOTA_NULL, WOTA_FALSE, etc.) */
|
/* Symbol codes (WOTA_NULL, WOTA_FALSE, etc.) */
|
||||||
void wota_write_sym (WotaBuffer *wb, int sym_code);
|
void wota_write_sym (WotaBuffer *wb, int sym_code);
|
||||||
|
void wota_write_int_word(WotaBuffer *wb, long long val);
|
||||||
|
void wota_write_float_word(WotaBuffer *wb, double val);
|
||||||
|
|
||||||
|
|
||||||
#ifdef WOTA_IMPLEMENTATION
|
#ifdef WOTA_IMPLEMENTATION
|
||||||
@@ -496,7 +498,7 @@ static int fits_in_56_bits(long long x)
|
|||||||
Write a WOTA_INT (single 64-bit word):
|
Write a WOTA_INT (single 64-bit word):
|
||||||
top 56 bits = signed integer (arithmetic shift), LSB=0x00
|
top 56 bits = signed integer (arithmetic shift), LSB=0x00
|
||||||
*/
|
*/
|
||||||
static void wota_write_int_word(WotaBuffer *wb, long long val)
|
void wota_write_int_word(WotaBuffer *wb, long long val)
|
||||||
{
|
{
|
||||||
/* shift 'val' left by 8 bits into the top 56,
|
/* shift 'val' left by 8 bits into the top 56,
|
||||||
then OR the type code in the bottom byte. */
|
then OR the type code in the bottom byte. */
|
||||||
@@ -511,7 +513,7 @@ static void wota_write_int_word(WotaBuffer *wb, long long val)
|
|||||||
first word => type=0x01 in LSB, top 56 bits=0
|
first word => type=0x01 in LSB, top 56 bits=0
|
||||||
second word => raw IEEE 754 double bits
|
second word => raw IEEE 754 double bits
|
||||||
*/
|
*/
|
||||||
static void wota_write_float_word(WotaBuffer *wb, double val)
|
void wota_write_float_word(WotaBuffer *wb, double val)
|
||||||
{
|
{
|
||||||
uint64_t *p = wota_buffer_alloc(wb, 2);
|
uint64_t *p = wota_buffer_alloc(wb, 2);
|
||||||
p[0] = (uint64_t)WOTA_FLOAT; /* top 56 bits=0, LSB=0x01 */
|
p[0] = (uint64_t)WOTA_FLOAT; /* top 56 bits=0, LSB=0x01 */
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ var transform = use('transform');
|
|||||||
var rasterize = use('rasterize');
|
var rasterize = use('rasterize');
|
||||||
var video_actor = use('sdl_video')
|
var video_actor = use('sdl_video')
|
||||||
|
|
||||||
|
var graphics
|
||||||
|
|
||||||
var window
|
var window
|
||||||
var render
|
var render
|
||||||
|
|
||||||
@@ -42,12 +44,18 @@ send(video_actor, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render = e.id
|
render = e.id
|
||||||
|
graphics = use('graphics', video_actor, e.id)
|
||||||
console.log(`Created window and renderer id ${render}`)
|
console.log(`Created window and renderer id ${render}`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
var last = os.now()
|
var last = os.now()
|
||||||
|
|
||||||
|
// FPS tracking
|
||||||
|
var fps_samples = []
|
||||||
|
var fps_sample_count = 60
|
||||||
|
var fps_sum = 0
|
||||||
|
|
||||||
// Engine state
|
// Engine state
|
||||||
var camera = {
|
var camera = {
|
||||||
x: 0,
|
x: 0,
|
||||||
@@ -56,8 +64,12 @@ var camera = {
|
|||||||
rotation: 0
|
rotation: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var images = {}
|
||||||
|
|
||||||
|
|
||||||
// Convert high-level draw commands to low-level renderer commands
|
// Convert high-level draw commands to low-level renderer commands
|
||||||
function translate_draw_commands(commands) {
|
function translate_draw_commands(commands) {
|
||||||
|
if (!graphics) return
|
||||||
var renderer_commands = []
|
var renderer_commands = []
|
||||||
|
|
||||||
commands.forEach(function(cmd) {
|
commands.forEach(function(cmd) {
|
||||||
@@ -152,10 +164,16 @@ function translate_draw_commands(commands) {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case "draw_image":
|
case "draw_image":
|
||||||
|
var img = graphics.texture(cmd.image)
|
||||||
|
if (!img.gpu) break
|
||||||
// TODO: Handle image loading and texture management
|
// TODO: Handle image loading and texture management
|
||||||
renderer_commands.push({
|
renderer_commands.push({
|
||||||
op: "texture",
|
op: "texture",
|
||||||
data: cmd
|
data: {
|
||||||
|
texture_id: img.gpu.id,
|
||||||
|
dst: {x: cmd.rect.x, y: cmd.rect.y, width: img.width, height:img.height},
|
||||||
|
src: {x:0,y:0,width:img.width,height:img.height},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -215,7 +233,27 @@ function loop()
|
|||||||
data: batch_commands
|
data: batch_commands
|
||||||
}, _ => {
|
}, _ => {
|
||||||
var diff = os.now() - now
|
var diff = os.now() - now
|
||||||
$_.delay(loop,1/240)
|
|
||||||
|
// Calculate and track FPS
|
||||||
|
var frame_time = os.now() - last
|
||||||
|
if (frame_time > 0) {
|
||||||
|
var current_fps = 1 / frame_time
|
||||||
|
|
||||||
|
// Add to samples
|
||||||
|
fps_samples.push(current_fps)
|
||||||
|
fps_sum += current_fps
|
||||||
|
|
||||||
|
// Keep only the last N samples
|
||||||
|
if (fps_samples.length > fps_sample_count) {
|
||||||
|
fps_sum -= fps_samples.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate average FPS
|
||||||
|
var avg_fps = fps_sum / fps_samples.length
|
||||||
|
console.log(`FPS: ${avg_fps.toFixed(1)}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
loop()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ function draw()
|
|||||||
{color: color.yellow}
|
{color: color.yellow}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
draw2d.image("tests/bunny")
|
||||||
|
|
||||||
// Return the draw commands
|
// Return the draw commands
|
||||||
return draw2d.get_commands()
|
return draw2d.get_commands()
|
||||||
}
|
}
|
||||||
|
|||||||
1
tests/spawnee.js
Normal file
1
tests/spawnee.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log("im alive")
|
||||||
12
tests/spawner.js
Normal file
12
tests/spawner.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
function spawnem()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 10; i++)
|
||||||
|
$_.start(_ => {}, "tests/spawnee.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
with ([1,2,3]) {
|
||||||
|
console.log(toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
$_.delay(spawnem, 3)
|
||||||
Reference in New Issue
Block a user