removed nuke; restored quickjs due to mem leaks

This commit is contained in:
John Alanbrook 2023-10-03 22:16:38 +00:00
parent f5c7b0433d
commit 2b402d7a2d
28 changed files with 273 additions and 33698 deletions

View file

@ -44,9 +44,6 @@
#include "list.h"
#include "quickjs.h"
#include "libregexp.h"
#undef CONFIG_BIGNUM
#ifdef CONFIG_BIGNUM
#include "libbf.h"
#endif
@ -59,8 +56,6 @@
#define DIRECT_DISPATCH 1
#endif
#define JS_TYPEDARRAY
#if defined(__APPLE__)
#define MALLOC_OVERHEAD 0
#else
@ -97,11 +92,11 @@
*/
//#define DUMP_BYTECODE (1)
/* dump the occurence of the automatic GC */
//#define DUMP_GC
#define DUMP_GC
/* dump objects freed by the garbage collector */
//#define DUMP_GC_FREE
#define DUMP_GC_FREE
/* dump objects leaking when freeing the runtime */
//#define DUMP_LEAKS 1
#define DUMP_LEAKS 1
/* dump memory usage before running the garbage collector */
//#define DUMP_MEM
//#define DUMP_OBJECTS /* dump objects in JS_FreeContext */
@ -1465,7 +1460,6 @@ static JSClassShortDef const js_std_class_def[] = {
{ JS_ATOM_GeneratorFunction, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_GENERATOR_FUNCTION */
{ JS_ATOM_ForInIterator, js_for_in_iterator_finalizer, js_for_in_iterator_mark }, /* JS_CLASS_FOR_IN_ITERATOR */
{ JS_ATOM_RegExp, js_regexp_finalizer, NULL }, /* JS_CLASS_REGEXP */
#ifdef JS_TYPEDARRAY
{ JS_ATOM_ArrayBuffer, js_array_buffer_finalizer, NULL }, /* JS_CLASS_ARRAY_BUFFER */
{ JS_ATOM_SharedArrayBuffer, js_array_buffer_finalizer, NULL }, /* JS_CLASS_SHARED_ARRAY_BUFFER */
{ JS_ATOM_Uint8ClampedArray, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT8C_ARRAY */
@ -1475,16 +1469,13 @@ static JSClassShortDef const js_std_class_def[] = {
{ JS_ATOM_Uint16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT16_ARRAY */
{ JS_ATOM_Int32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT32_ARRAY */
{ JS_ATOM_Uint32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT32_ARRAY */
#ifdef CONFIG_BIGNUM
{ JS_ATOM_BigInt64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_INT64_ARRAY */
{ JS_ATOM_BigUint64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_UINT64_ARRAY */
#endif
{ JS_ATOM_Float32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT32_ARRAY */
{ JS_ATOM_Float64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT64_ARRAY */
{ JS_ATOM_DataView, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_DATAVIEW */
#endif
#ifdef CONFIG_BIGNUM
{ JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */
{ JS_ATOM_BigFloat, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_FLOAT */
@ -1492,20 +1483,16 @@ static JSClassShortDef const js_std_class_def[] = {
{ JS_ATOM_BigDecimal, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_DECIMAL */
{ JS_ATOM_OperatorSet, js_operator_set_finalizer, js_operator_set_mark }, /* JS_CLASS_OPERATOR_SET */
#endif
#ifdef JS_MAP
{ JS_ATOM_Map, js_map_finalizer, js_map_mark }, /* JS_CLASS_MAP */
{ JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */
{ JS_ATOM_WeakMap, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKMAP */
{ JS_ATOM_WeakSet, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKSET */
{ JS_ATOM_Map_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_MAP_ITERATOR */
{ JS_ATOM_Set_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_SET_ITERATOR */
#endif
{ JS_ATOM_Array_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_ARRAY_ITERATOR */
{ JS_ATOM_String_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_STRING_ITERATOR */
{ JS_ATOM_RegExp_String_Iterator, js_regexp_string_iterator_finalizer, js_regexp_string_iterator_mark }, /* JS_CLASS_REGEXP_STRING_ITERATOR */
#ifdef JS_PROMISE
{ JS_ATOM_Generator, js_generator_finalizer, js_generator_mark }, /* JS_CLASS_GENERATOR */
#endif
};
static int init_class_range(JSRuntime *rt, JSClassShortDef const *tab,
@ -1661,9 +1648,7 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function;
rt->class_array[JS_CLASS_C_FUNCTION_DATA].call = js_c_function_data_call;
rt->class_array[JS_CLASS_BOUND_FUNCTION].call = js_call_bound_function;
#ifdef JS_PROMISE
rt->class_array[JS_CLASS_GENERATOR_FUNCTION].call = js_generator_function_call;
#endif
if (init_shape_hash(rt))
goto fail;
@ -2173,13 +2158,13 @@ JSContext *JS_NewContext(JSRuntime *rt)
JS_AddIntrinsicBaseObjects(ctx);
JS_AddIntrinsicDate(ctx);
JS_AddIntrinsicEval(ctx);
// JS_AddIntrinsicStringNormalize(ctx);
JS_AddIntrinsicStringNormalize(ctx);
JS_AddIntrinsicRegExp(ctx);
JS_AddIntrinsicJSON(ctx);
// JS_AddIntrinsicProxy(ctx);
// JS_AddIntrinsicMapSet(ctx);
// JS_AddIntrinsicTypedArrays(ctx);
// JS_AddIntrinsicPromise(ctx);
JS_AddIntrinsicProxy(ctx);
JS_AddIntrinsicMapSet(ctx);
JS_AddIntrinsicTypedArrays(ctx);
JS_AddIntrinsicPromise(ctx);
#ifdef CONFIG_BIGNUM
JS_AddIntrinsicBigInt(ctx);
#endif
@ -5432,11 +5417,9 @@ static void free_object(JSRuntime *rt, JSObject *p)
p->shape = NULL;
p->prop = NULL;
#ifdef JS_MAP
if (unlikely(p->first_weak_ref)) {
reset_weak_ref(rt, p);
}
#endif
finalizer = rt->class_array[p->class_id].finalizer;
if (finalizer)
@ -5664,7 +5647,6 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
JS_MarkValue(rt, *var_ref->pvalue, mark_func);
}
break;
#ifdef JS_PROMISE
case JS_GC_OBJ_TYPE_ASYNC_FUNCTION:
{
JSAsyncFunctionData *s = (JSAsyncFunctionData *)gp;
@ -5674,7 +5656,6 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
JS_MarkValue(rt, s->resolving_funcs[1], mark_func);
}
break;
#endif
case JS_GC_OBJ_TYPE_SHAPE:
{
JSShape *sh = (JSShape *)gp;
@ -6844,10 +6825,8 @@ static int JS_SetPrototypeInternal(JSContext *ctx, JSValueConst obj,
if (throw_flag && JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)
return TRUE;
#ifdef JS_PROXY
if (unlikely(p->class_id == JS_CLASS_PROXY))
return js_proxy_setPrototypeOf(ctx, obj, proto_val, throw_flag);
#endif
sh = p->shape;
if (sh->proto == proto)
return TRUE;
@ -6937,8 +6916,6 @@ JSValue JS_GetPrototype(JSContext *ctx, JSValueConst obj)
if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) {
JSObject *p;
p = JS_VALUE_GET_OBJ(obj);
#ifdef JS_PROXY
if (unlikely(p->class_id == JS_CLASS_PROXY)) {
val = js_proxy_getPrototypeOf(ctx, obj);
} else {
@ -6948,13 +6925,6 @@ JSValue JS_GetPrototype(JSContext *ctx, JSValueConst obj)
else
val = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
}
#else
p = p->shape->proto;
if (!p)
val = JS_NULL;
else
val = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p));
#endif
} else {
val = JS_DupValue(ctx, JS_GetPrototypePrimitive(ctx, obj));
}
@ -7776,11 +7746,9 @@ int JS_IsExtensible(JSContext *ctx, JSValueConst obj)
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
return FALSE;
p = JS_VALUE_GET_OBJ(obj);
#ifdef JS_PROXY
if (unlikely(p->class_id == JS_CLASS_PROXY))
return js_proxy_isExtensible(ctx, obj);
else
#endif
return p->extensible;
}
@ -7792,10 +7760,8 @@ int JS_PreventExtensions(JSContext *ctx, JSValueConst obj)
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
return FALSE;
p = JS_VALUE_GET_OBJ(obj);
#ifdef JS_PROXY
if (unlikely(p->class_id == JS_CLASS_PROXY))
return js_proxy_preventExtensions(ctx, obj);
#endif
p->extensible = FALSE;
return TRUE;
}
@ -12005,11 +11971,9 @@ int JS_IsArray(JSContext *ctx, JSValueConst val)
JSObject *p;
if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) {
p = JS_VALUE_GET_OBJ(val);
#ifdef JS_PROXY
if (unlikely(p->class_id == JS_CLASS_PROXY))
return js_proxy_isArray(ctx, val);
else
#endif
return p->class_id == JS_CLASS_ARRAY;
} else {
return FALSE;
@ -15304,7 +15268,6 @@ static JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, BOOL is_async)
{
JSValue method, ret, sync_iter;
#ifdef JS_PROMISE
if (is_async) {
method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_asyncIterator);
if (JS_IsException(method))
@ -15321,9 +15284,7 @@ static JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, BOOL is_async)
JS_FreeValue(ctx, sync_iter);
return ret;
}
} else
#endif
{
} else {
method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator);
if (JS_IsException(method))
return method;
@ -18788,7 +18749,6 @@ static JSContext *JS_GetFunctionRealm(JSContext *ctx, JSValueConst func_obj)
realm = b->realm;
}
break;
#ifdef JS_PROXY
case JS_CLASS_PROXY:
{
JSProxyData *s = p->u.opaque;
@ -18802,7 +18762,6 @@ static JSContext *JS_GetFunctionRealm(JSContext *ctx, JSValueConst func_obj)
}
}
break;
#endif
case JS_CLASS_BOUND_FUNCTION:
{
JSBoundFunction *bf = p->u.bound_function;
@ -18926,7 +18885,6 @@ static JSValue JS_InvokeFree(JSContext *ctx, JSValue this_val, JSAtom atom,
}
/* JSAsyncFunctionState (used by generator and async functions) */
#ifdef JS_PROMISE
static __exception int async_func_init(JSContext *ctx, JSAsyncFunctionState *s,
JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv)
@ -19807,7 +19765,6 @@ static JSValue js_async_generator_function_call(JSContext *ctx, JSValueConst fun
js_async_generator_free(ctx->rt, s);
return JS_EXCEPTION;
}
#endif
/* JS parser */
@ -28311,13 +28268,11 @@ static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier)
if (JS_IsException(basename_val))
return basename_val;
#ifdef JS_PROMISE
promise = JS_NewPromiseCapability(ctx, resolving_funcs);
if (JS_IsException(promise)) {
JS_FreeValue(ctx, basename_val);
return promise;
}
#endif
args[0] = resolving_funcs[0];
args[1] = resolving_funcs[1];
@ -41757,18 +41712,14 @@ static const JSCFunctionListEntry js_string_proto_normalize[] = {
};
#endif
void JS_AddIntrinsicStringNormalize(JSContext *ctx)
{
#ifdef JS_STRINGNORMALIZE
#ifdef CONFIG_ALL_UNICODE
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_STRING], js_string_proto_normalize,
countof(js_string_proto_normalize));
#endif
#endif
}
/* Math */
/* precondition: a and b are not NaN */
@ -44461,7 +44412,6 @@ static const JSCFunctionListEntry js_reflect_obj[] = {
};
/* Proxy */
#ifdef JS_PROXY
static void js_proxy_finalizer(JSRuntime *rt, JSValue val)
{
@ -45414,8 +45364,6 @@ void JS_AddIntrinsicProxy(JSContext *ctx)
obj1, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
}
#endif
/* Symbol */
static JSValue js_symbol_constructor(JSContext *ctx, JSValueConst new_target,
@ -45528,7 +45476,6 @@ static const JSCFunctionListEntry js_symbol_funcs[] = {
};
/* Set/Map/WeakSet/WeakMap */
#ifdef JS_MAP
typedef struct JSMapRecord {
int ref_count; /* used during enumeration to avoid freeing the record */
@ -46276,7 +46223,6 @@ static const uint8_t js_map_proto_funcs_count[6] = {
countof(js_set_iterator_proto_funcs),
};
void JS_AddIntrinsicMapSet(JSContext *ctx)
{
int i;
@ -46307,10 +46253,8 @@ void JS_AddIntrinsicMapSet(JSContext *ctx)
js_map_proto_funcs_count[i + 4]);
}
}
#endif
/* Generator */
#ifdef JS_PROMISE
static const JSCFunctionListEntry js_generator_function_proto_funcs[] = {
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "GeneratorFunction", JS_PROP_CONFIGURABLE),
};
@ -46324,7 +46268,6 @@ static const JSCFunctionListEntry js_generator_proto_funcs[] = {
/* Promise */
typedef enum JSPromiseStateEnum {
JS_PROMISE_PENDING,
JS_PROMISE_FULFILLED,
@ -47549,7 +47492,6 @@ static JSClassShortDef const js_async_class_def[] = {
{ JS_ATOM_AsyncGenerator, js_async_generator_finalizer, js_async_generator_mark }, /* JS_CLASS_ASYNC_GENERATOR */
};
void JS_AddIntrinsicPromise(JSContext *ctx)
{
JSRuntime *rt = ctx->rt;
@ -47634,7 +47576,7 @@ void JS_AddIntrinsicPromise(JSContext *ctx)
0, JS_PROP_CONFIGURABLE);
JS_FreeValue(ctx, obj1);
}
#endif
/* URI handling */
static int string_get_hex(JSString *p, int k, int n) {
@ -51139,7 +51081,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
}
/* ES6 Generator */
#ifdef JS_PROMISE
ctx->class_proto[JS_CLASS_GENERATOR] = JS_NewObjectProto(ctx, ctx->iterator_proto);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_GENERATOR],
js_generator_proto_funcs,
@ -51159,7 +51100,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
JS_SetConstructor2(ctx, obj1, ctx->class_proto[JS_CLASS_GENERATOR_FUNCTION],
0, JS_PROP_CONFIGURABLE);
JS_FreeValue(ctx, obj1);
#endif
/* global properties */
ctx->eval_obj = JS_NewCFunction(ctx, js_global_eval, "eval", 1);
JS_DefinePropertyValue(ctx, ctx->global_obj, JS_ATOM_eval,
@ -51172,7 +51113,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
}
/* Typed Arrays */
#ifdef JS_TYPEDARRAY
static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT] = {
0, 0, 0, 1, 1, 2, 2,
#ifdef CONFIG_BIGNUM
@ -53538,7 +53479,7 @@ static const JSCFunctionListEntry js_dataview_proto_funcs[] = {
JS_CFUNC_MAGIC_DEF("setFloat64", 2, js_dataview_setValue, JS_CLASS_FLOAT64_ARRAY ),
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "DataView", JS_PROP_CONFIGURABLE ),
};
#endif
/* Atomics */
#ifdef CONFIG_ATOMICS
@ -54031,11 +53972,8 @@ void JS_AddIntrinsicAtomics(JSContext *ctx)
JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_atomics_obj, countof(js_atomics_obj));
}
#endif
#endif /* CONFIG_ATOMICS */
/* CONFIG_ATOMICS */
#ifdef JS_TYPEDARRAY
void JS_AddIntrinsicTypedArrays(JSContext *ctx)
{
JSValue typed_array_base_proto, typed_array_base_func;
@ -54121,4 +54059,3 @@ void JS_AddIntrinsicTypedArrays(JSContext *ctx)
JS_AddIntrinsicAtomics(ctx);
#endif
}
#endif

View file

@ -366,7 +366,7 @@ void JS_AddIntrinsicStringNormalize(JSContext *ctx);
void JS_AddIntrinsicRegExpCompiler(JSContext *ctx);
void JS_AddIntrinsicRegExp(JSContext *ctx);
void JS_AddIntrinsicJSON(JSContext *ctx);
//void JS_AddIntrinsicProxy(JSContext *ctx);
void JS_AddIntrinsicProxy(JSContext *ctx);
void JS_AddIntrinsicMapSet(JSContext *ctx);
void JS_AddIntrinsicTypedArrays(JSContext *ctx);
void JS_AddIntrinsicPromise(JSContext *ctx);

View file

@ -146,94 +146,6 @@ var Profile = {
get fps() { return sys_cmd(8); },
};
var Nuke = {
newline(cols) { nuke(3, cols ? cols : 1); },
newrow(height) { nuke(13,height); },
wins: {},
curwin:"",
prop(str, v) {
var ret = nuke(2, str, v);
if (Number.isFinite(ret)) return ret;
return 0;
},
treeid: 0,
tree(str) { var on = nuke(11, str, this.treeid); this.treeid++; return on; },
tree_pop() { nuke(12);},
prop_num(str, num) { return nuke(2, str, num, -1e10, 1e10, 0.01); },
prop_bool(str, val) { return nuke(4, str, val); },
checkbox(val) { return nuke(4,"",val); },
label(str) { nuke(5, str); },
textbox(str) { return nuke(7, str); },
scrolltext(str) { nuke(14,str); },
defaultrect: { x:10, y:10, w:400, h:600 },
window(name) {
this.curwin = name;
var rect;
if (name in this.wins)
rect = this.wins[name];
else
rect = { x:10, y:10, w:400, h:600 };
nuke(0, name, rect);
},
button(name) { return nuke(6, name); },
radio(name, val, cmp) { return nuke(9, name, val, cmp); },
img(path) { nuke(8, path); },
end() {
this.wins[this.curwin] = nuke(10);
this.treeid = 0;
nuke(1);
},
pprop(str, p, nonew) {
switch(typeof p) {
case 'number':
if (!nonew) Nuke.newline();
return Nuke.prop_num(str, p);
break;
case 'boolean':
if (!nonew) Nuke.newline();
return Nuke.prop_bool(str, p);
case 'object':
if (Array.isArray(p)) {
var arr = [];
Nuke.newline(p.length+1);
Nuke.label(str);
arr[0] = Nuke.pprop("#x", p[0], true);
arr[1] = Nuke.pprop("#y", p[1], true);
return arr;
} else {
if (!nonew)Nuke.newline(2);
Nuke.label(str);
Nuke.label(p);
}
break;
case 'string':
if (!nonew) Nuke.newline();
Nuke.label(str);
return Nuke.textbox(p);
default:
if (!nonew) Nuke.newline(2);
Nuke.label(str);
Nuke.label(p);
}
},
};
Object.defineProperty(Nuke, "curwin", {enumerable:false});
Object.defineProperty(Nuke, "defaultrect", {enumerable:false});
/* These controls are available during editing, and during play of debug builds */
var DebugControls = {};
DebugControls.inputs = {};

View file

@ -19,8 +19,6 @@ var configs = {
};
var editor = {
dbgdraw: false,
selected: undefined,
selectlist: [],
grablist: [],
scalelist: [],
@ -379,6 +377,7 @@ var editor = {
GUI.text("WORKING LAYER: " + this.working_layer, [0,520]);
GUI.text("MODE: " + this.edit_mode, [0,500]);
Debug.point(world2screen(this.cursor), 2, Color.green);
if (this.comp_info && this.sel_comp) {
@ -387,7 +386,7 @@ var editor = {
GUI.text("0,0", world2screen([0,0]));
var clvl = this.edit_level;
var clvl = this.selectlist.length === 1 ? this.selectlist[0] : this.edit_level;
var lvlchain = [];
while (clvl !== Primum) {
lvlchain.push(clvl);
@ -401,11 +400,12 @@ var editor = {
var ypos = 200;
lvlchain.reverse();
lvlchain.forEach(function(x) {
lvlchain.forEach(function(x,i) {
lvlcolor = colormap.sample(lvlcolorsample);
var lvlstr = x.toString();
if (x.dirty)
lvlstr += "*";
if (i === lvlchain.length-1) lvlstr += "[this]";
GUI.text(lvlstr, [0, ypos], 1, lvlcolor);
lvlcolorsample -= 0.1;
@ -1260,15 +1260,7 @@ var inputpanel = {
stolen: {},
gui() {
Nuke.window(this.title);
Nuke.newline();
this.guibody();
if (Nuke.button("close"))
this.close();
Nuke.end();
return false;
},
guibody() {
@ -1386,12 +1378,9 @@ var replpanel = Object.copy(inputpanel, {
title: "REPL",
closeonsubmit:false,
guibody() {
Nuke.newrow(400);
var log = cmd(84);
var f = log.prev('\n', 0,10);
Nuke.scrolltext(log.slice(f));
Nuke.newrow(30);
this.value = Nuke.textbox(this.value);
GUI.text(log, [400,60], 1, Color.white, 600, [0,0]);
GUI.text(this.value, [400,50], 1, Color.green, 600);
},
action() {
@ -1591,7 +1580,7 @@ var openlevelpanel = Object.copy(inputpanel, {
keycb() { this.assets = this.allassets.filter(x => x.search(this.value) !== -1); },
guibody() {
this.value = Nuke.textbox(this.value);
GUI.text(this.value, [100,600], 1, Color.green, 600);
this.assets.forEach(function(x) {
if (Nuke.button(x)) {

View file

@ -311,8 +311,10 @@ var gameobject = {
var objects = {};
this.ur.objects ??= {};
if (!Object.keys(this.objects).equal(Object.keys(this.ur.objects))) {
for (var o in this.objects)
for (var o in this.objects) {
objects[o] = this.objects[o].transform_obj();
objects[o].ur = this.objects[o].ur.toString();
}
} else {
for (var o in this.objects) {
var obj = this.objects[o].json_obj();
@ -446,6 +448,7 @@ var gameobject = {
for (var prop in ur.objects) {
var o = ur.objects[prop];
var newobj = obj.spawn(prototypes.get_ur(o.ur));
if (!newobj) continue;
obj.rename_obj(newobj.toString(), prop);
}
}
@ -642,6 +645,10 @@ prototypes.file2ur = function(file)
*/
prototypes.get_ur = function(name)
{
if (!name) {
Log.warn(`Can't get ur from an undefined.`);
return;
}
var urpath = name;
if (urpath.includes('/'))
urpath = prototypes.file2ur(name);

View file

@ -1,13 +1,23 @@
var GUI = {
text(str, pos, size, color, wrap) {
text(str, pos, size, color, wrap, anchor) {
size ??= 1;
color ??= Color.white;
wrap ??= -1;
anchor ??= [0,1];
var bb = cmd(118, str, size, wrap);
var opos = [bb.r, bb.t];
var w = bb.r*2;
var h = bb.t*2;
var h = ui_text(str, pos, size, color, wrap);
//ui_text draws with an anchor on top left corner
var p = pos.slice();
p.x -= w * anchor.x;
bb.r += (w*anchor.x);
bb.l += (w*anchor.x);
p.y += h * (1 - anchor.y);
bb.t += h*(1-anchor.y);
bb.b += h*(1-anchor.y);
ui_text(str, p, size, color, wrap);
return bb;
},

View file

@ -2,7 +2,6 @@
#include "debug.h"
#include "gameobject.h"
#include "nuke.h"
#include <string.h>
#include "debugdraw.h"
@ -102,6 +101,8 @@ int *phys2d_query_box_points(cpVect pos, cpVect wh, cpVect *points, int n) {
arrpush(qhits, i);
}
cpShapeFree(box);
return qhits;
}

View file

@ -1,5 +1,4 @@
#include "render.h"
#include "nuke.h"
#define SOKOL_TRACE_HOOKS
#define SOKOL_IMPL

View file

@ -26,7 +26,7 @@ char *catstr[] = {"engine", "script", "render"};
FILE *logfile = NULL;
#define ERROR_BUFFER 1024
#define CONSOLE_BUF 1024*1024*5 /* 5MB */
#define CONSOLE_BUF 1024*1024 /* 5MB */
char *lastlog;
char *consolelog;

View file

@ -44,6 +44,18 @@ static JSValue globalThis;
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
void js_setprop_str(JSValue obj, const char *prop, JSValue v)
{
JS_SetPropertyStr(js, obj, prop, v);
// JS_FreeValue(js,v);
}
void js_setprop_num(JSValue obj, uint32_t i, JSValue v)
{
JS_SetPropertyUint32(js, obj, i, v);
// JS_FreeValue(js,v);
}
JSValue js_getpropstr(JSValue v, const char *str)
{
JSValue p = JS_GetPropertyStr(js,v,str);
@ -84,7 +96,7 @@ JSValue strarr2js(const char **c)
{
JSValue arr = JS_NewArray(js);
for (int i = 0; i < arrlen(c); i++)
JS_SetPropertyUint32(js, arr, i, JS_NewString(js, c[i]));
js_setprop_num(arr,i,JS_NewString(js, c[i]));
return arr;
}
@ -169,6 +181,9 @@ struct rgba js2color(JSValue v) {
.a = a*RGBA_MAX,
};
for (int i = 0; i < 4; i++)
JS_FreeValue(js,c[i]);
return color;
}
@ -201,22 +216,24 @@ cpBitmask js2bitmask(JSValue v) {
return mask;
}
cpVect *cpvecarr = NULL;
cpVect *js2cpvec2arr(JSValue v) {
if (cpvecarr)
arrfree(cpvecarr);
int n = js_arrlen(v);
cpVect *points = NULL;
for (int i = 0; i < n; i++)
arrput(points, js2vec2(js_getpropidx( v, i)));
arrput(cpvecarr, js2vec2(js_getpropidx( v, i)));
return points;
return cpvecarr;
}
JSValue bitmask2js(cpBitmask mask) {
JSValue arr = JS_NewArray(js);
for (int i = 0; i < 11; i++) {
int on = mask & 1 << i;
JS_SetPropertyUint32(js, arr, i, JS_NewBool(js, on));
}
for (int i = 0; i < 11; i++)
js_setprop_num(arr,i,JS_NewBool(js,mask & 1 << i));
return arr;
}
@ -228,8 +245,8 @@ void vec2float(cpVect v, float *f) {
JSValue vec2js(cpVect v) {
JSValue array = JS_NewArray(js);
JS_SetPropertyInt64(js, array, 0, JS_NewFloat64(js, v.x));
JS_SetPropertyInt64(js, array, 1, JS_NewFloat64(js, v.y));
js_setprop_num(array,0,JS_NewFloat64(js,v.x));
js_setprop_num(array,1,JS_NewFloat64(js,v.y));
return array;
}
@ -242,7 +259,8 @@ JSValue v22js(HMM_Vec2 v)
JSValue vecarr2js(cpVect *points, int n) {
JSValue array = JS_NewArray(js);
for (int i = 0; i < n; i++)
JS_SetPropertyInt64(js, array, i, vec2js(points[i]));
js_setprop_num(array,i,vec2js(points[i]));
return array;
}
@ -297,131 +315,26 @@ struct rect js2rect(JSValue v) {
return rect;
}
JSValue rect2js(struct rect rect) {
JSValue obj = JS_NewObject(js);
JS_SetPropertyStr(js, obj, "x", JS_NewFloat64(js, rect.x));
JS_SetPropertyStr(js, obj, "y", JS_NewFloat64(js, rect.y));
JS_SetPropertyStr(js, obj, "w", JS_NewFloat64(js, rect.w));
JS_SetPropertyStr(js, obj, "h", JS_NewFloat64(js, rect.h));
js_setprop_str(obj, "x", JS_NewFloat64(js, rect.x));
js_setprop_str(obj, "y", JS_NewFloat64(js, rect.y));
js_setprop_str(obj, "w", JS_NewFloat64(js, rect.w));
js_setprop_str(obj, "h", JS_NewFloat64(js, rect.h));
return obj;
}
JSValue bb2js(struct boundingbox bb)
{
JSValue obj = JS_NewObject(js);
JS_SetPropertyStr(js,obj,"t", JS_NewFloat64(js,bb.t));
JS_SetPropertyStr(js,obj,"b", JS_NewFloat64(js,bb.b));
JS_SetPropertyStr(js,obj,"r", JS_NewFloat64(js,bb.r));
JS_SetPropertyStr(js,obj,"l", JS_NewFloat64(js,bb.l));
js_setprop_str(obj,"t", JS_NewFloat64(js,bb.t));
js_setprop_str(obj,"b", JS_NewFloat64(js,bb.b));
js_setprop_str(obj,"r", JS_NewFloat64(js,bb.r));
js_setprop_str(obj,"l", JS_NewFloat64(js,bb.l));
return obj;
}
#ifndef NO_EDITOR
#include "nuke.h"
JSValue duk_nuke(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
int cmd = js2int(argv[0]);
float editnum;
int editint;
char textbox[130];
const char *str = NULL;
if (JS_IsString(argv[1]))
str = JS_ToCString(js, argv[1]);
else {
JSValue tostr = JS_ToString(js, argv[1]);
str = JS_ToCString(js, argv[1]);
JS_FreeValue(js, tostr);
}
struct rect rect = (struct rect){0, 0, 0, 0};
JSValue ret = JS_NULL;
switch (cmd) {
case 0:
rect = js2rect(argv[2]);
nuke_begin(str, rect);
break;
case 1:
nuke_stop();
break;
case 2:
editnum = js2number(argv[2]);
nuke_property_float(str, js2number(argv[3]), &editnum, js2number(argv[4]), js2number(argv[5]), js2number(argv[5]));
ret = JS_NewFloat64(js, editnum);
break;
case 3:
nuke_nel(js2number(argv[1]));
break;
case 4:
editint = JS_ToBool(js, argv[2]);
nuke_checkbox(str, &editint);
ret = JS_NewBool(js, editint);
break;
case 5:
nuke_label(str);
break;
case 6:
ret = JS_NewBool(js, nuke_btn(str));
break;
case 7:
strncpy(textbox, str, 130);
nuke_edit_str(textbox);
ret = JS_NewString(js, textbox);
break;
case 8:
nuke_img(str);
break;
case 9:
editint = js2int(argv[2]);
nuke_radio_btn(str, &editint, js2int(argv[3]));
ret = JS_NewInt64(js, editint);
break;
case 10:
rect = nuke_win_get_bounds();
ret = rect2js(rect);
break;
case 11:
ret = JS_NewBool(js, nuke_push_tree_id(str, js2int(argv[2])));
break;
case 12:
nuke_tree_pop();
return JS_NULL;
case 13:
nuke_row(js2int(argv[1]));
break;
case 14:
nuke_scrolltext(str);
break;
case 15:
nuke_nel_h(js2int(argv[1]), js2int(argv[2]));
break;
}
if (str)
JS_FreeCString(js, str);
return ret;
}
#endif
JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
static_assert(sizeof(tsReal) * 2 == sizeof(cpVect));
@ -463,9 +376,9 @@ JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst
for (int i = 0; i < nsamples; i++) {
JSValue psample = JS_NewArray(js);
JS_SetPropertyUint32(js, psample, 0, float2js(samples[i].x));
JS_SetPropertyUint32(js, psample, 1, float2js(samples[i].y));
JS_SetPropertyUint32(js, arr, i, psample);
js_setprop_num(psample, 0, float2js(samples[i].x));
js_setprop_num(psample, 1, float2js(samples[i].y));
js_setprop_num(arr, i, psample);
}
ts_bspline_free(&spline);
@ -476,7 +389,7 @@ JSValue duk_spline_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst
JSValue ints2js(int *ints) {
JSValue arr = JS_NewArray(js);
for (int i = 0; i < arrlen(ints); i++)
JS_SetPropertyUint32(js, arr, i, int2js(ints[i]));
js_setprop_num(arr,i,int2js(ints[i]));
return arr;
}
@ -557,6 +470,8 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
int cmd = js2int(argv[0]);
const char *str = NULL;
const char *str2 = NULL;
const void *d1 = NULL;
const void *d2 = NULL;
JSValue ret = JS_NULL;
switch (cmd) {
@ -652,14 +567,16 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 21:
return JS_NewBool(js, shape_get_sensor(js2ptr(argv[1])));
ret = JS_NewBool(js, shape_get_sensor(js2ptr(argv[1])));
break;
case 22:
shape_enabled(js2ptr(argv[1]), JS_ToBool(js, argv[2]));
break;
case 23:
return JS_NewBool(js, shape_is_enabled(js2ptr(argv[1])));
ret = JS_NewBool(js, shape_is_enabled(js2ptr(argv[1])));
break;
case 24:
timer_pause(js2timer(argv[1]));
@ -682,43 +599,48 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 29:
return JS_NewFloat64(js, js2timer(argv[1])->interval);
ret = JS_NewFloat64(js, js2timer(argv[1])->interval);
break;
case 30:
sprite_setanim(id2sprite(js2int(argv[1])), js2ptr(argv[2]), js2int(argv[3]));
return JS_NULL;
break;
case 31:
free(js2ptr(argv[1]));
break;
case 32:
return JS_NewFloat64(js, js2timer(argv[1])->remain_time);
ret = JS_NewFloat64(js, js2timer(argv[1])->remain_time);
break;
case 33:
return JS_NewBool(js, js2timer(argv[1])->on);
ret = JS_NewBool(js, js2timer(argv[1])->on);
break;
case 34:
return JS_NewBool(js, js2timer(argv[1])->repeat);
ret = JS_NewBool(js, js2timer(argv[1])->repeat);
break;
case 35:
js2timer(argv[1])->repeat = JS_ToBool(js, argv[2]);
return JS_NULL;
break;
case 36:
id2go(js2int(argv[1]))->scale = js2number(argv[2]);
gameobject_apply(id2go(js2int(argv[1])));
cpSpaceReindexShapesForBody(space, id2go(js2int(argv[1]))->body);
return JS_NULL;
break;
case 37:
if (!id2sprite(js2int(argv[1]))) return JS_NULL;
if (!id2sprite(js2int(argv[1]))) break;
id2sprite(js2int(argv[1]))->pos = js2hmmv2(argv[2]);
break;
case 38:
str = JS_ToCString(js, argv[1]);
ret = JS_NewString(js, slurp_text(str, NULL));
d1 = slurp_text(str,NULL);
ret = JS_NewString(js, d1);
break;
case 39:
@ -738,68 +660,79 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 42:
return bitmask2js(id2go(js2int(argv[1]))->filter.categories);
ret = bitmask2js(id2go(js2int(argv[1]))->filter.categories);
break;
case 43:
return bitmask2js(id2go(js2int(argv[1]))->filter.mask);
ret = bitmask2js(id2go(js2int(argv[1]))->filter.mask);
break;
case 44:
return JS_NewInt64(js, pos2gameobject(js2vec2(argv[1])));
ret = JS_NewInt64(js, pos2gameobject(js2vec2(argv[1])));
break;
case 45:
return vec2js(mouse_pos);
ret = vec2js(mouse_pos);
break;
case 46:
set_mouse_mode(js2int(argv[1]));
return JS_NULL;
break;
case 47:
draw_grid(js2number(argv[1]), js2number(argv[2]), js2color(argv[3]));
return JS_NULL;
break;
case 48:
return JS_NewInt64(js, mainwin.width);
ret = JS_NewInt64(js, mainwin.width);
break;
case 49:
return JS_NewInt64(js, mainwin.height);
ret = JS_NewInt64(js, mainwin.height);
break;
case 50:
return JS_NewBool(js, action_down(js2int(argv[1])));
ret = JS_NewBool(js, action_down(js2int(argv[1])));
break;
case 51:
draw_cppoint(js2vec2(argv[1]), js2number(argv[2]), js2color(argv[3]));
return JS_NULL;
break;
case 52:
return ints2js(phys2d_query_box(js2vec2(argv[1]), js2vec2(argv[2])));
ret = ints2js(phys2d_query_box(js2vec2(argv[1]), js2vec2(argv[2])));
break;
case 53:
draw_box(js2vec2(argv[1]), js2vec2(argv[2]), js2color(argv[3]));
return JS_NULL;
break;
case 54:
gameobject_apply(js2go(argv[1]));
return JS_NULL;
break;
case 55:
js2go(argv[1])->flipx = JS_ToBool(js, argv[2]) ? -1 : 1;
return JS_NULL;
break;
case 56:
js2go(argv[1])->flipy = JS_ToBool(js, argv[2]) ? -1 : 1;
return JS_NULL;
break;
case 57:
return JS_NewBool(js, js2go(argv[1])->flipx == -1 ? 1 : 0);
ret = JS_NewBool(js, js2go(argv[1])->flipx == -1 ? 1 : 0);
break;
case 58:
return JS_NewBool(js, js2go(argv[1])->flipy == -1 ? 1 : 0);
ret = JS_NewBool(js, js2go(argv[1])->flipy == -1 ? 1 : 0);
break;
case 59:
return JS_NewInt64(js, point2segindex(js2vec2(argv[1]), js2cpvec2arr(argv[2]), js2number(argv[3])));
ret = JS_NewInt64(js, point2segindex(js2vec2(argv[1]), js2cpvec2arr(argv[2]), js2number(argv[3])));
break;
case 60:
if (!id2sprite(js2int(argv[1]))) return JS_NULL;
if (!id2sprite(js2int(argv[1]))) break;
id2sprite(js2int(argv[1]))->layer = js2int(argv[2]);
break;
@ -812,7 +745,8 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 63:
return JS_NewFloat64(js, deltaT);
ret = JS_NewFloat64(js, deltaT);
break;
case 64:
str = JS_ToCString(js, argv[1]);
@ -841,28 +775,32 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 70:
return vec2js(world2go(js2go(argv[1]), js2vec2(argv[2])));
ret = vec2js(world2go(js2go(argv[1]), js2vec2(argv[2])));
break;
case 71:
return vec2js(go2world(js2go(argv[1]), js2vec2(argv[2])));
ret = vec2js(go2world(js2go(argv[1]), js2vec2(argv[2])));
break;
case 72:
return vec2js(cpSpaceGetGravity(space));
ret = vec2js(cpSpaceGetGravity(space));
break;
case 73:
cpSpaceSetDamping(space, js2number(argv[1]));
return JS_NULL;
break;
case 74:
return JS_NewFloat64(js, cpSpaceGetDamping(space));
ret = JS_NewFloat64(js, cpSpaceGetDamping(space));
break;
case 75:
js2go(argv[1])->layer = js2int(argv[2]);
return JS_NULL;
break;
case 76:
set_cat_mask(js2int(argv[1]), js2bitmask(argv[2]));
return JS_NULL;
break;
case 77:
break;
@ -871,31 +809,36 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 79:
return JS_NewBool(js, phys_stepping());
ret = JS_NewBool(js, phys_stepping());
break;
case 80:
return ints2js(phys2d_query_shape(js2ptr(argv[1])));
ret = ints2js(phys2d_query_shape(js2ptr(argv[1])));
break;
case 81:
draw_arrow(js2vec2(argv[1]), js2vec2(argv[2]), js2color(argv[3]), js2int(argv[4]));
return JS_NULL;
break;
case 82:
gameobject_draw_debug(js2int(argv[1]));
return JS_NULL;
break;
case 83:
draw_edge(js2cpvec2arr(argv[1]), js_arrlen(argv[1]), js2color(argv[2]), js2number(argv[3]), 0, 0, js2color(argv[2]), 10);
return JS_NULL;
break;
case 84:
return JS_NewString(js, consolelog);
ret = JS_NewString(js, consolelog);
break;
case 85:
return vec2js(cpvproject(js2vec2(argv[1]), js2vec2(argv[2])));
ret = vec2js(cpvproject(js2vec2(argv[1]), js2vec2(argv[2])));
break;
case 86:
return ints2js(phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), js2cpvec2arr(argv[3]), js2int(argv[4])));
ret = ints2js(phys2d_query_box_points(js2vec2(argv[1]), js2vec2(argv[2]), js2cpvec2arr(argv[3]), js2int(argv[4])));
break;
case 87:
str = JS_ToCString(js, argv[1]);
@ -904,11 +847,11 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 88:
// mini_music_pause();
return JS_NULL;
break;
case 89:
// mini_music_stop();
return JS_NULL;
break;
case 90:
str = JS_ToCString(js, argv[1]);
@ -969,48 +912,60 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 103:
return num2js(js2go(argv[1])->scale);
ret = num2js(js2go(argv[1])->scale);
break;
case 104:
return bool2js(js2go(argv[1])->flipx == -1 ? 1 : 0);
ret = bool2js(js2go(argv[1])->flipx == -1 ? 1 : 0);
break;
case 105:
return bool2js(js2go(argv[1])->flipy == -1 ? 1 : 0);
ret = bool2js(js2go(argv[1])->flipy == -1 ? 1 : 0);
break;
case 106:
js2go(argv[1])->e = js2number(argv[2]);
break;
case 107:
return num2js(js2go(argv[1])->e);
ret = num2js(js2go(argv[1])->e);
break;
case 108:
js2go(argv[1])->f = js2number(argv[2]);
break;
case 109:
return num2js(js2go(argv[1])->f);
ret = num2js(js2go(argv[1])->f);
break;
case 110:
return num2js(js2go(argv[1])->e);
ret = num2js(js2go(argv[1])->e);
break;
case 111:
return v22js(js2sprite(argv[1])->pos);
ret = v22js(js2sprite(argv[1])->pos);
break;
case 112:
return num2js(((struct phys2d_edge*)js2ptr(argv[1]))->thickness);
ret = num2js(((struct phys2d_edge*)js2ptr(argv[1]))->thickness);
break;
case 113:
js2go(argv[1])->ref = JS_DupValue(js,argv[2]);
break;
case 114:
return bool2js(js2sprite(argv[1])->enabled);
ret = bool2js(js2sprite(argv[1])->enabled);
break;
case 115:
draw_circle(js2vec2(argv[1]), js2number(argv[2]), js2number(argv[2]), js2color(argv[3]), -1);
break;
case 116:
return str2js(tex_get_path(js2sprite(argv[1])->tex));
ret = str2js(tex_get_path(js2sprite(argv[1])->tex));
break;
case 117:
str = JS_ToCString(js, argv[1]);
@ -1031,7 +986,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
ret = str2js(engine_info());
break;
case 121:
return num2js(get_timescale());
ret = num2js(get_timescale());
break;
case 122:
break;
@ -1117,8 +1072,12 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
if (str2)
JS_FreeCString(js, str2);
if (!JS_IsNull(ret))
if (d1) free(d1);
if (d2) free(d2);
if (!JS_IsNull(ret)) {
return ret;
}
return JS_NULL;
}
@ -1392,7 +1351,7 @@ JSValue duk_q_body(JSContext *js, JSValueConst this, int argc, JSValueConst *arg
JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
JSValue sprite = JS_NewObject(js);
JS_SetPropertyStr(js,sprite,"id",JS_NewInt64(js, make_sprite(js2int(argv[0]))));
js_setprop_str(sprite,"id",JS_NewInt64(js, make_sprite(js2int(argv[0]))));
return sprite;
}
@ -1423,8 +1382,8 @@ JSValue duk_make_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst
phys2d_applybox(box);
JSValue boxval = JS_NewObject(js);
JS_SetPropertyStr(js, boxval, "id", ptr2js(box));
JS_SetPropertyStr(js, boxval, "shape", ptr2js(&box->shape));
js_setprop_str(boxval, "id", ptr2js(box));
js_setprop_str(boxval, "shape", ptr2js(&box->shape));
return boxval;
}
@ -1463,8 +1422,8 @@ JSValue duk_make_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCon
struct phys2d_circle *circle = Make2DCircle(go);
JSValue circleval = JS_NewObject(js);
JS_SetPropertyStr(js, circleval, "id", ptr2js(circle));
JS_SetPropertyStr(js, circleval, "shape", ptr2js(&circle->shape));
js_setprop_str(circleval, "id", ptr2js(circle));
js_setprop_str(circleval, "shape", ptr2js(&circle->shape));
return circleval;
}
@ -1500,8 +1459,8 @@ JSValue duk_make_poly2d(JSContext *js, JSValueConst this, int argc, JSValueConst
phys2d_poly_setverts(poly, js2cpvec2arr(argv[1]));
JSValue polyval = JS_NewObject(js);
JS_SetPropertyStr(js, polyval, "id", ptr2js(poly));
JS_SetPropertyStr(js, polyval, "shape", ptr2js(&poly->shape));
js_setprop_str(polyval, "id", ptr2js(poly));
js_setprop_str(polyval, "shape", ptr2js(&poly->shape));
return polyval;
}
@ -1534,8 +1493,8 @@ JSValue duk_make_edge2d(JSContext *js, JSValueConst this, int argc, JSValueConst
}
JSValue edgeval = JS_NewObject(js);
JS_SetPropertyStr(js, edgeval, "id", ptr2js(edge));
JS_SetPropertyStr(js, edgeval, "shape", ptr2js(&edge->shape));
js_setprop_str(edgeval, "id", ptr2js(edge));
js_setprop_str(edgeval, "shape", ptr2js(&edge->shape));
return edgeval;
}
@ -1571,8 +1530,8 @@ JSValue duk_inflate_cpv(JSContext *js, JSValueConst this, int argc, JSValueConst
inflatepoints(inflate_in, points, -d, n);
JSValue arr = JS_NewArray(js);
JS_SetPropertyUint32(js, arr, 0, vecarr2js(inflate_out, n));
JS_SetPropertyUint32(js, arr, 1, vecarr2js(inflate_in, n));
js_setprop_num(arr, 0, vecarr2js(inflate_out, n));
js_setprop_num(arr, 1, vecarr2js(inflate_in, n));
return arr;
}
@ -1596,6 +1555,7 @@ JSValue duk_anim(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
YughInfo("Val is now %f at time %f", anim_val(a, i), i);
JSValue vv = num2js(anim_val(a, i));
JS_Call(js, prop, globalThis, 1, &vv);
JS_FreeValue(js,vv);
}
return JS_NULL;
@ -1637,10 +1597,6 @@ void ffi_load() {
DUK_FUNC(yughlog, 4)
#ifndef NO_EDITOR
DUK_FUNC(nuke, 6)
#endif
DUK_FUNC(make_gameobject, 0)
DUK_FUNC(set_body, 3)
DUK_FUNC(q_body, 2)

View file

@ -118,7 +118,7 @@ struct sFont *MakeFont(const char *fontfile, int height) {
struct sFont *newfont = calloc(1, sizeof(struct sFont));
newfont->height = height;
unsigned char *ttf_buffer = slurp_file(fontfile, NULL);
unsigned char *ttf_buffer = slurp_text(fontfile, NULL);
unsigned char *bitmap = malloc(packsize * packsize);
stbtt_packedchar glyphs[95];
@ -150,8 +150,6 @@ struct sFont *MakeFont(const char *fontfile, int height) {
.ptr = bitmap,
.size = packsize * packsize}});
free(ttf_buffer);
free(bitmap);
for (unsigned char c = 32; c < 127; c++) {
stbtt_packedchar glyph = glyphs[c - 32];
@ -173,6 +171,9 @@ struct sFont *MakeFont(const char *fontfile, int height) {
newfont->Characters[c].rect = r;
}
free(ttf_buffer);
free(bitmap);
return newfont;
}
@ -243,48 +244,39 @@ struct boundingbox text_bb(const char *text, float scale, float lw, float tracki
{
HMM_Vec2 cursor = {0,0};
const unsigned char *c = text;
const unsigned char *wordstart;
const unsigned char *line, *wordstart, *drawstart;
line = drawstart = (unsigned char *)text;
while (*c != '\0') {
if (isblank(*c)) {
cursor.X += font->Characters[*c].Advance * tracking * scale;
c++;
} else if (isspace(*c)) {
while (*line != '\0') {
if (isblank(*line)) {
cursor.X += font->Characters[*line].Advance * tracking * scale;
line++;
} else if (isspace(*line)) {
cursor.Y -= scale * font->linegap;
cursor.X = 0;
c++;
line++;
} else {
wordstart = c;
int wordwidth = 0;
wordstart = line;
int wordWidth = 0;
while (!isspace(*c) && *c != '\0') {
wordwidth += font->Characters[*c].Advance * tracking * scale;
c++;
while (!isspace(*line) && *line != '\0') {
wordWidth += font->Characters[*line].Advance * tracking * scale;
line++;
}
if (lw > 0 && (cursor.X + wordwidth) >= lw) {
if (lw > 0 && (cursor.X + wordWidth) >= lw) {
cursor.X = 0;
cursor.Y -= scale * font->linegap;
cursor.Y -= scale * font->linegap;
}
while (wordstart < c) {
while (wordstart < line) {
cursor.X += font->Characters[*wordstart].Advance * tracking * scale;
wordstart++;
wordstart++;
}
}
}
float height = cursor.Y + (font->height*scale);
float width = lw > 0 ? lw : cursor.X;
struct boundingbox bb = {};
bb.l = 0;
bb.t = font->ascent * font->emscale * scale;
bb.b = font->descent * font->emscale * scale;
bb.r = cursor.X;
return bb;
return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){width,height});
return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){cursor.X,-cursor.Y});
}
/* pos given in screen coordinates */

View file

@ -4,7 +4,6 @@
#include "debugdraw.h"
#include "input.h"
#include "log.h"
#include "nuke.h"
#include "resources.h"
#include "script.h"
#include "shader.h"
@ -252,68 +251,6 @@ void gameobject_setpos(struct gameobject *go, cpVect vec) {
phys2d_reindex_body(go->body);
}
void object_gui(struct gameobject *go) {
/*
float temp_pos[2];
draw_cppoint(cpBodyGetPosition(go->body), 3);
nuke_property_float2("Position", -1000000.f, temp_pos, 1000000.f, 1.f, 0.5f);
cpVect tvect = { temp_pos[0], temp_pos[1] };
cpBodySetPosition(go->body, tvect);
float mtry = cpBodyGetAngle(go->body);
float modtry = fmodf(mtry * RAD2DEGS, 360.f);
if (modtry < 0.f)
modtry += 360.f;
float modtry2 = modtry;
nuke_property_float("Angle", -1000.f, &modtry, 1000.f, 0.5f, 0.5f);
modtry -= modtry2;
cpBodySetAngle(go->body, mtry + (modtry * DEG2RADS));
nuke_property_float("Scale", 0.f, &go->scale, 1000.f, 0.01f, go->scale * 0.01f);
nuke_nel(3);
nuke_radio_btn("Static", &go->bodytype, CP_BODY_TYPE_STATIC);
nuke_radio_btn("Dynamic", &go->bodytype, CP_BODY_TYPE_DYNAMIC);
nuke_radio_btn("Kinematic", &go->bodytype, CP_BODY_TYPE_KINEMATIC);
cpBodySetType(go->body, go->bodytype);
if (go->bodytype == CP_BODY_TYPE_DYNAMIC) {
nuke_property_float("Mass", 0.01f, &go->mass, 1000.f, 0.01f, 0.01f);
cpBodySetMass(go->body, go->mass);
}
nuke_property_float("Friction", 0.f, &go->f, 10.f, 0.01f, 0.01f);
nuke_property_float("Elasticity", 0.f, &go->e, 2.f, 0.01f, 0.01f);
int n = -1;
for (int i = 0; i < arrlen(go->components); i++) {
struct component *c = &go->components[i];
comp_draw_debug(c);
nuke_nel(5);
if (nuke_btn("Del")) n = i;
if (nuke_push_tree_id(c->ref->name, i)) {
comp_draw_gui(c);
nuke_tree_pop();
}
}
if (n >= 0)
gameobject_delcomponent(go, n);
*/
}
void body_draw_shapes_dbg(cpBody *body, cpShape *shape, void *data) {
struct phys2d_shape *s = cpShapeGetUserData(shape);
s->debugdraw(s->data);

View file

@ -61,7 +61,7 @@ JSValue input2js(const char *input) {
sh_new_arena(jshash);
JSValue n = str2js(input);
shput(jshash, input, str2js(input));
shput(jshash, input, n);
return n;
}
@ -178,6 +178,7 @@ void input_btn(int btn, int state, uint32_t mod)
argv[0] = JS_NewString(js, "action");
script_callee(pawn_callee, 3, argv);
JS_FreeValue(js, argv[0]);
JS_FreeValue(js, argv[1]);

View file

@ -1,165 +0,0 @@
#include "nuke.h"
#ifndef NO_EDITOR
#include "config.h"
#define NK_PRIVATE
#define STB_IMAGE_STATIC
#define STBTT_STATIC
#define NK_IMPLEMENTATION
#include "nuklear.h"
#define SOKOL_NUKLEAR_IMPL
#include "sokol/sokol_nuklear.h"
#include <stdarg.h>
#include "log.h"
#include "texture.h"
#include "window.h"
#define MAX_VERTEX_BUFFER 512 * 1024
#define MAX_ELEMENT_BUFFER 128 * 1024
struct nk_context *ctx;
void nuke_init(struct window *win) {
snk_setup(&(snk_desc_t){
.no_default_font = false,
.dpi_scale = sapp_dpi_scale(),
});
ctx = snk_new_frame();
}
struct rect nk2rect(struct nk_rect rect)
{
struct rect r;
r.x = rect.x;
r.y = rect.y;
r.w = rect.w;
r.h = rect.h;
return r;
}
struct nk_rect rect2nk(struct rect rect)
{
struct nk_rect r;
r.x = rect.x;
r.y = rect.y;
r.w = rect.w;
r.h = rect.h;
return r;
}
void nuke_start() {
ctx = snk_new_frame();
}
void nuke_end() {
snk_render(sapp_width(), sapp_height());
}
int nuke_begin(const char *lbl, struct rect rect) {
return nk_begin(ctx, lbl, rect2nk(rect), NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_TITLE);
}
int nuke_begin_win(const char *lbl) {
return nk_begin(ctx, lbl, nk_rect(10, 10, 400, 600), NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_TITLE);
}
void nuke_stop() {
nk_end(ctx);
}
struct rect nuke_win_get_bounds() {
return nk2rect(nk_window_get_bounds(ctx));
}
void nuke_row(int height) {
nk_layout_row_dynamic(ctx, height, 1);
}
void nuke_property_float3(const char *label, float min, float *val, float max, float step, float dragstep) {
nk_layout_row_dynamic(ctx, 25, 1);
nk_label(ctx, label, NK_TEXT_LEFT);
nk_layout_row_dynamic(ctx, 25, 3);
nuke_property_float("#X", min, &val[0], max, step, dragstep);
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
nuke_property_float("#Z", min, &val[2], max, step, dragstep);
}
void nuke_property_float2(const char *label, float min, float *val, float max, float step, float dragstep) {
nk_layout_row_dynamic(ctx, 25, 1);
nk_label(ctx, label, NK_TEXT_LEFT);
nk_layout_row_dynamic(ctx, 25, 2);
nuke_property_float("#X", min, &val[0], max, step, dragstep);
nuke_property_float("#Y", min, &val[1], max, step, dragstep);
}
void nuke_property_float(const char *lbl, float min, float *val, float max, float step, float dragstep) {
nk_property_float(ctx, lbl, min, val, max, step, dragstep);
}
int nuke_btn(const char *lbl) {
return nk_button_label(ctx, lbl);
}
void nuke_img(char *path) {
/*
struct Texture *t = texture_pullfromfile(path);
nk_layout_row_static(ctx, t->height, t->width, 1);
nk_image(ctx, nk_image_id(t->id));
*/
}
void nuke_property_int(const char *lbl, int min, int *val, int max, int step) {
nk_property_int(ctx, lbl, min, val, max, step, step);
}
void nuke_radio_btn(const char *lbl, int *val, int cmp) {
if (nk_option_label(ctx, lbl, *val == cmp)) *val = cmp;
}
void nuke_checkbox(const char *lbl, int *val) {
nk_checkbox_label(ctx, lbl, val);
}
void nuke_scrolltext(char *str) {
nk_edit_string_zero_terminated(ctx, NK_EDIT_MULTILINE | NK_EDIT_GOTO_END_ON_ACTIVATE, str, 1024 * 1024 * 5, NULL);
}
void nuke_nel(int cols) {
nk_layout_row_dynamic(ctx, 25, cols);
}
void nuke_nel_h(int cols, int h) {
nk_layout_row_dynamic(ctx, h, cols);
}
void nuke_label(const char *s) {
nk_label(ctx, s, NK_TEXT_LEFT);
}
void nuke_edit_str(char *str) {
nk_edit_string_zero_terminated(ctx, NK_EDIT_BOX | NK_EDIT_NO_HORIZONTAL_SCROLL, str, 130, nk_filter_ascii);
}
int nuke_push_tree_id(const char *name, int id) {
return nk_tree_push_id(ctx, NK_TREE_NODE, name, NK_MINIMIZED, id);
}
void nuke_tree_pop() {
nk_tree_pop(ctx);
}
void nuke_labelf(const char *fmt, ...) {
char buf[512];
va_list args;
va_start(args, fmt);
vsnprintf(buf, 512, fmt, args);
nuke_label(buf);
va_end(args);
}
#endif

View file

@ -1,58 +0,0 @@
#ifndef NUKE_H
#define NUKE_H
#include "render.h"
#define NK_INCLUDE_STANDARD_IO
#define NK_KEYSTATE_BASED_INPUT
#define NK_INCLUDE_FIXED_TYPES
#define NK_INCLUDE_STANDARD_VARARGS
#define NK_INCLUDE_FONT_BAKING
#define NK_INCLUDE_DEFAULT_FONT
#define NK_INCLUDE_STANDARD_BOOL
#define NK_INCLUDE_DEFAULT_ALLOCATOR
#define NK_INCLUDE_STANDARD_IO
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
#include "sokol/sokol_gfx.h"
#include "sokol/sokol_app.h"
#include "nuklear.h"
#include "sokol/sokol_nuklear.h"
struct window;
void nuke_init(struct window *win);
void nuke_start();
void nuke_end();
int nuke_begin(const char *lbl, struct rect rect);
int nuke_begin_win(const char *lbl);
void nuke_stop();
struct rect nuke_win_get_bounds();
void nuke_property_float(const char *lbl, float min, float *val, float max, float step, float dragstep);
#define nuke_prop_float nuke_property_float
void nuke_property_float2(const char *label, float min, float *val, float max, float step, float dragstep);
void nuke_property_float3(const char *label, float min, float *val, float max, float step, float dragstep);
void nuke_property_int(const char *lbl, int min, int *val, int max, int step);
void nuke_radio_btn(const char *lbl, int *val, int cmp);
void nuke_checkbox(const char *lbl, int *val);
void nuke_nel_h(int cols, int h);
void nuke_nel(int cols);
void nuke_row(int height);
void nuke_label(const char *s);
void nuke_prop_float(const char *label, float min, float *val, float max, float step, float dragstep);
void nuke_edit_str(char *str);
void nuke_img(char *path);
void nuke_scrolltext(char *str);
int nuke_push_tree_id(const char *name, int id);
void nuke_tree_pop();
int nuke_btn(const char *lbl);
void nuke_labelf(const char *fmt, ...);
#endif

View file

@ -7,7 +7,6 @@
#include "font.h"
#include "gameobject.h"
#include "log.h"
#include "nuke.h"
#include "shader.h"
#include "sprite.h"
#include "window.h"
@ -283,10 +282,6 @@ void render_init() {
debugdraw_init();
sprite_initialize();
#ifndef NO_EDITOR
nuke_init(&mainwin);
#endif
model_init();
sg_color c;
rgba2floats(&c, editorClearColor);
@ -519,19 +514,11 @@ void full_2d_pass(struct window *window)
////// TEXT && GUI
debug_nextpass();
#ifndef NO_EDITOR
nuke_start();
#endif
call_gui();
debug_flush(&hudproj);
text_flush(&hudproj);
sprite_flush();
#ifndef NO_EDITOR
call_nk_gui();
nuke_end();
#endif
}
void full_3d_pass(struct window *window)

View file

@ -185,7 +185,7 @@ void *cdb_slurp(struct cdb *cdb, const char *file, size_t *size)
unsigned vlen, vpos;
vpos = cdb_datapos(cdb);
vlen = cdb_datalen(cdb);
char *data = malloc(vlen);
char *data = malloc(vlen+1);
cdb_read(cdb, data, vlen, vpos);
if (size) *size = vlen;
return data;

View file

@ -49,6 +49,17 @@ void script_startup() {
// jso_file("scripts/engine.js");
}
void script_stop()
{
JS_RunGC(rt);
JS_FreeRuntime(rt);
}
void script_gc()
{
JS_RunGC(rt);
}
JSValue num_cache[100] = {0};
int js_print_exception(JSValue v) {
@ -56,9 +67,10 @@ int js_print_exception(JSValue v) {
if (JS_IsException(v)) {
JSValue exception = JS_GetException(js);
/* TODO: Does it need freed if null? */
if (JS_IsNull(exception))
if (JS_IsNull(exception)) {
JS_FreeValue(js,exception);
return 0;
}
JSValue val = JS_GetPropertyStr(js, exception, "stack");
const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name"));
@ -125,7 +137,8 @@ void js_dump_stack() {
}
int script_dofile(const char *file) {
script_runfile(file);
JSValue ret = script_runfile(file);
JS_FreeValue(js,ret);
return file_mod_secs(file);
}
@ -187,6 +200,15 @@ void script_call_sym(JSValue sym) {
call_callee(&c);
}
void out_memusage(const char *file)
{
FILE *f = fopen(file, "w");
JSMemoryUsage jsmem;
JS_ComputeMemoryUsage(rt, &jsmem);
JS_DumpMemoryUsage(f, &jsmem, rt);
fclose(f);
}
JSValue js_callee_exec(struct callee *c, int argc, JSValue *argv)
{
JSValue ret = JS_Call(js, c->fn, c->obj, argc, argv);

View file

@ -28,6 +28,8 @@ void script_draw();
void duk_run_err();
void js_dump_stack();
void out_memusage(const char *f);
void script_editor();
void script_call(const char *f);
void script_call_sym(JSValue sym);

View file

@ -174,6 +174,9 @@ struct Texture *texture_pullfromfile(const char *path) {
shput(texhash, path, tex);
for (int i = 1; i < mips; i++)
free(mipdata[i]);
return tex;
}

View file

@ -1,205 +0,0 @@
# Nuklear
[![](https://github.com/Immediate-Mode-UI/Nuklear/workflows/C%2FC++%20CI/badge.svg )](https://github.com/Immediate-Mode-UI/Nuklear/actions)
This is a minimal-state, immediate-mode graphical user interface toolkit
written in ANSI C and licensed under public domain. It was designed as a simple
embeddable user interface for application and does not have any dependencies,
a default render backend or OS window/input handling but instead provides a
highly modular, library-based approach, with simple input state for input and
draw commands describing primitive shapes as output. So instead of providing a
layered library that tries to abstract over a number of platform and
render backends, it focuses only on the actual UI.
## Features
- Immediate-mode graphical user interface toolkit
- Single-header library
- Written in C89 (ANSI C)
- Small codebase (~18kLOC)
- Focus on portability, efficiency and simplicity
- No dependencies (not even the standard library if not wanted)
- Fully skinnable and customizable
- Low memory footprint with total control of memory usage if needed / wanted
- UTF-8 support
- No global or hidden state
- Customizable library modules (you can compile and use only what you need)
- Optional font baker and vertex buffer output
- [Documentation](https://Immediate-Mode-UI.github.io/Nuklear/doc/nuklear.html)
## Building
This library is self-contained in one single header file and can be used either
in header-only mode or in implementation mode. The header-only mode is used
by default when included and allows including this header in other headers
and does not contain the actual implementation.
The implementation mode requires defining the preprocessor macro
`NK_IMPLEMENTATION` in *one* .c/.cpp file before `#include`ing this file, e.g.:
```c
#define NK_IMPLEMENTATION
#include "nuklear.h"
```
IMPORTANT: Every time you include "nuklear.h" you have to define the same optional flags.
This is very important; not doing it either leads to compiler errors, or even worse, stack corruptions.
## Gallery
![screenshot](https://cloud.githubusercontent.com/assets/8057201/11761525/ae06f0ca-a0c6-11e5-819d-5610b25f6ef4.gif)
![screen](https://cloud.githubusercontent.com/assets/8057201/13538240/acd96876-e249-11e5-9547-5ac0b19667a0.png)
![screen2](https://cloud.githubusercontent.com/assets/8057201/13538243/b04acd4c-e249-11e5-8fd2-ad7744a5b446.png)
![node](https://cloud.githubusercontent.com/assets/8057201/9976995/e81ac04a-5ef7-11e5-872b-acd54fbeee03.gif)
![skinning](https://cloud.githubusercontent.com/assets/8057201/15991632/76494854-30b8-11e6-9555-a69840d0d50b.png)
![gamepad](https://cloud.githubusercontent.com/assets/8057201/14902576/339926a8-0d9c-11e6-9fee-a8b73af04473.png)
## Example
```c
/* init gui state */
struct nk_context ctx;
nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);
enum {EASY, HARD};
static int op = EASY;
static float value = 0.6f;
static int i = 20;
if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
/* fixed widget pixel width */
nk_layout_row_static(&ctx, 30, 80, 1);
if (nk_button_label(&ctx, "button")) {
/* event handling */
}
/* fixed widget window ratio width */
nk_layout_row_dynamic(&ctx, 30, 2);
if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY;
if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD;
/* custom widget pixel width */
nk_layout_row_begin(&ctx, NK_STATIC, 30, 2);
{
nk_layout_row_push(&ctx, 50);
nk_label(&ctx, "Volume:", NK_TEXT_LEFT);
nk_layout_row_push(&ctx, 110);
nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
}
nk_layout_row_end(&ctx);
}
nk_end(&ctx);
```
![example](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png)
## Bindings
There are a number of nuklear bindings for different languages created by other authors.
I cannot attest for their quality since I am not necessarily proficient in any of these
languages. Furthermore there are no guarantee that all bindings will always be kept up to date:
- [Java](https://github.com/glegris/nuklear4j) by Guillaume Legris
- [D](https://github.com/Timu5/bindbc-nuklear) by Mateusz Muszyński
- [Golang](https://github.com/golang-ui/nuklear) by golang-ui@github.com
- [Rust](https://github.com/snuk182/nuklear-rust) by snuk182@github.com
- [Chicken](https://github.com/wasamasa/nuklear) by wasamasa@github.com
- [Nim](https://github.com/zacharycarter/nuklear-nim) by zacharycarter@github.com
- Lua
- [LÖVE-Nuklear](https://github.com/keharriso/love-nuklear) by Kevin Harrison
- [MoonNuklear](https://github.com/stetre/moonnuklear) by Stefano Trettel
- Python
- [pyNuklear](https://github.com/billsix/pyNuklear) by William Emerison Six (ctypes-based wrapper)
- [pynk](https://github.com/nathanrw/nuklear-cffi) by nathanrw@github.com (cffi binding)
- [CSharp/.NET](https://github.com/cartman300/NuklearDotNet) by cartman300@github.com
- [V](https://github.com/nsauzede/vnk) by Nicolas Sauzede
## Credits
Developed by Micha Mettke and every direct or indirect contributor to the GitHub.
Embeds `stb_texedit`, `stb_truetype` and `stb_rectpack` by Sean Barrett (public domain)
Embeds `ProggyClean.ttf` font by Tristan Grimmer (MIT license).
Big thank you to Omar Cornut (ocornut@github) for his [imgui](https://github.com/ocornut/imgui) library and
giving me the inspiration for this library, Casey Muratori for handmade hero
and his original immediate-mode graphical user interface idea and Sean
Barrett for his amazing single-header [libraries](https://github.com/nothings/stb) which restored my faith
in libraries and brought me to create some of my own. Finally Apoorva Joshi for his single-header [file packer](http://apoorvaj.io/single-header-packer.html).
## License
```
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Micha Mettke
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----------------------------------------------------------------------------
```
## Reviewers guide
When reviewing pull request there are common things a reviewer should keep
in mind.
Reviewing changes to `src/*` and `nuklear.h`:
* Ensure C89 compatibility.
* The code should work for several backends to an acceptable degree.
* Check no other parts of `nuklear.h` are related to the PR and thus nothing is missing.
* Recommend simple optimizations.
* Pass small structs by value instead of by pointer.
* Use local buffers over heap allocation when possible.
* Check that the coding style is consistent with code around it.
* Variable/function name casing.
* Indentation.
* Curly bracket (`{}`) placement.
* Ensure that the contributor has bumped the appropriate version in
[clib.json](https://github.com/Immediate-Mode-UI/Nuklear/blob/master/clib.json)
and added their changes to the
[CHANGELOG](https://github.com/Immediate-Mode-UI/Nuklear/blob/master/src/CHANGELOG).
* Have at least one other person review the changes before merging.
Reviewing changes to `demo/*`, `example/*` and other files in the repo:
* Focus on getting working code merged.
* We want to make it easy for people to get started with Nuklear, and any
`demo` and `example` improvements helps in this regard.
* Use of newer C features, or even other languages is not discouraged.
* If another language is used, ensure that the build process is easy to figure out.
* Messy or less efficient code can be merged so long as these outliers are pointed out
and easy to find.
* Version shouldn't be bumped for these changes.
* Changes that improves code to be more inline with `nuklear.h` are ofc always welcome.

File diff suppressed because it is too large Load diff

View file

@ -1519,13 +1519,15 @@ _SOKOL_PRIVATE bool _saudio_alsa_backend_init(void) {
_SAUDIO_ERROR(ALSA_PTHREAD_CREATE_FAILED);
goto error;
}
snd_config_update_free_global();
return true;
error:
if (_saudio.backend.device) {
snd_pcm_close(_saudio.backend.device);
_saudio.backend.device = 0;
}
snd_config_update_free_global();
return false;
};
@ -1535,6 +1537,7 @@ _SOKOL_PRIVATE void _saudio_alsa_backend_shutdown(void) {
pthread_join(_saudio.backend.thread, 0);
snd_pcm_drain(_saudio.backend.device);
snd_pcm_close(_saudio.backend.device);
snd_config_update_free_global();
_saudio_free(_saudio.backend.buffer);
};

View file

@ -179,7 +179,6 @@
sg_commit()
--- at the end of your program, shutdown sokol_gfx with:
sg_shutdown()
--- if you need to destroy resources before sg_shutdown(), call:

File diff suppressed because it is too large Load diff

View file

@ -40,11 +40,3 @@ HMM_Vec3 trans_left(const struct mTransform *trans)
{
return HMM_QVRot(vLEFT, trans->rotation);
}
#include "nuke.h"
void trans_drawgui(struct mTransform *T) {
nuke_property_float3("Position", -1000.f, T->pos.Elements, 1000.f, 1.f, 1.f);
nuke_property_float3("Rotation", 0.f, T->rotation.Elements, 360.f, 1.f, 0.1f);
nuke_property_float("Scale", 0.f, &T->scale, 1000.f, 0.1f, 0.1f);
}

View file

@ -1,7 +1,6 @@
#include "window.h"
#include "input.h"
#include "log.h"
#include "nuke.h"
#include "script.h"
#include "texture.h"
#include <stdio.h>

View file

@ -34,10 +34,6 @@
#include "string.h"
#ifndef NO_EDITOR
#include "nuke.h"
#endif
#include "render.h"
#include "sokol/sokol_app.h"
@ -116,7 +112,7 @@ void seghandle(int sig) {
if (strsignal(sig))
YughCritical("CRASH! Signal: %s.", strsignal(sig));
print_stacktrace();
// print_stacktrace();
exit(1);
#endif
@ -189,14 +185,14 @@ void c_frame()
void c_clean() {
gif_rec_end("out.gif");
out_memusage("jsmem.txt");
script_stop();
saudio_shutdown();
sg_shutdown();
};
void c_event(const sapp_event *e)
{
#ifndef NO_EDITOR
snk_handle_event(e);
#endif
switch (e->type) {
case SAPP_EVENTTYPE_MOUSE_MOVE:
input_mouse_move(e->mouse_x, e->mouse_y, e->mouse_dx, e->mouse_dy, e->modifiers);