X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fnasal%2Fnasal.h;h=8b6b2c92866e5825dede03f9ba8c7fa9e34b41fe;hb=27a91062bda197ff0e5c3d95f43a2f89c353fdc5;hp=3c5140e0d20896022286ef0e87cadb64862a1b7a;hpb=a5ca531aac6e2334f28ad6a6aabd2268515b2d72;p=simgear.git diff --git a/simgear/nasal/nasal.h b/simgear/nasal/nasal.h index 3c5140e0..8b6b2c92 100644 --- a/simgear/nasal/nasal.h +++ b/simgear/nasal/nasal.h @@ -16,10 +16,14 @@ extern "C" { #endif typedef struct Context* naContext; - + // The function signature for an extension function: typedef naRef (*naCFunction)(naContext ctx, naRef me, int argc, naRef* args); +// The function signature for an extension function with userdata passed back: +typedef naRef (*naCFunctionU) + (naContext ctx, naRef me, int argc, naRef* args, void* user_data); + // All Nasal code runs under the watch of a naContext: naContext naNewContext(); void naFreeContext(naContext c); @@ -38,10 +42,25 @@ naContext naSubContext(naContext super); void naSetUserData(naContext c, void* p); void* naGetUserData(naContext c) GCC_PURE; +// run GC now (may block) +void naGC(); + // "Save" this object in the context, preventing it (and objects // referenced by it) from being garbage collected. +// TODO do we need a context? It is not used anyhow... void naSave(naContext ctx, naRef obj); +// "Save" this object and get a key which allows do mark the object as free +// later on (with naGCFree). +int naGCSave(naRef obj); + +// Release an object previously passed to naGCSave to allow it being cleaned up +// by the garbage collector. +void naGCRelease(int key); + +// Drop all saved references +void naClearSaved(); + // Similar, but the object is automatically released when the // context next runs native bytecode. Useful for saving off C-space // temporaries to protect them before passing back into a naCall. @@ -84,6 +103,28 @@ naRef naCall(naContext ctx, naRef func, int argc, naRef* args, // naModUnlock() first if the lock is already held. naRef naContinue(naContext ctx); +// Does a naCall() in a given context. Wrapped here to make lock +// tracking easier. Extension functions are called with the lock, but +// we have to release it before making a new naCall(). So rather than +// drop the lock in every extension function that might call back into +// Nasal, we keep a stack depth counter here and only unlock/lock +// around the naCall if it isn't the first one. +naRef naCallMethodCtx( naContext ctx, + naRef code, + naRef self, + int argc, + naRef* args, + naRef locals ); + +// Same as naCallMethodCtx but creates (and afterwards destroyes) a new context +naRef naCallMethod(naRef code, naRef self, int argc, naRef* args, naRef locals); + +typedef void (*naErrorHandler)(naContext); + +// Register a handler to be called if an error is raised during the execution of +// naCallMethodCtx or naCallMethod. +naErrorHandler naSetErrorHandler(naErrorHandler cb); + // Throw an error from the current call stack. This function makes a // longjmp call to a handler in naCall() and DOES NOT RETURN. It is // intended for use in library code that cannot otherwise report an @@ -119,6 +160,9 @@ naRef naInit_readline(naContext c); naRef naInit_gtk(naContext ctx); naRef naInit_cairo(naContext ctx); +// Returns a hash which can be used to add methods callable on strings +naRef naInit_string(naContext c); + // Context stack inspection, frame zero is the "top" int naStackDepth(naContext ctx); int naGetLine(naContext ctx, int frame); @@ -136,6 +180,9 @@ int naIsCode(naRef r) GCC_PURE; int naIsFunc(naRef r) GCC_PURE; int naIsCCode(naRef r) GCC_PURE; +// Object equality (check for same instance, aka. pointer equality) +int naIsIdentical(naRef l, naRef r) GCC_PURE; + // Allocators/generators: naRef naNil() GCC_PURE; naRef naNum(double num) GCC_PURE; @@ -143,7 +190,19 @@ naRef naNewString(naContext c); naRef naNewVector(naContext c); naRef naNewHash(naContext c); naRef naNewFunc(naContext c, naRef code); + +/** + * Register extension function + * + * @param fptr Pointer to C-function + * @param user_data Optional user data passed back on calling the function + * @param destroy Optional callback called if function gets freed by garbage + * collector to free user data if required. + */ naRef naNewCCode(naContext c, naCFunction fptr); +naRef naNewCCodeU(naContext c, naCFunctionU fptr, void* user_data); +naRef naNewCCodeUD(naContext c, naCFunctionU fptr, void* user_data, + void (*destroy)(void*)); // Some useful conversion/comparison routines int naEqual(naRef a, naRef b) GCC_PURE; @@ -159,15 +218,34 @@ naRef naStr_fromdata(naRef dst, const char* data, int len); naRef naStr_concat(naRef dest, naRef s1, naRef s2); naRef naStr_substr(naRef dest, naRef str, int start, int len); naRef naInternSymbol(naRef sym); +naRef getStringMethods(naContext c); // Vector utilities: int naVec_size(naRef v); naRef naVec_get(naRef v, int i); void naVec_set(naRef vec, int i, naRef o); int naVec_append(naRef vec, naRef o); -naRef naVec_removelast(naRef vec); void naVec_setsize(naContext c, naRef vec, int sz); +/** + * Remove and retrieve the first element of the vector. + * + * This operation reduces the size of the vector by one and moves all elements + * by one towards the begin of the vector. + * + * @return The element removed from the begin + */ +naRef naVec_removefirst(naRef vec); + +/** + * Remove and retrieve the last element of the vector. + * + * This operation reduces the size of the vector by one. + * + * @return The element removed from the end + */ +naRef naVec_removelast(naRef vec); + // Hash utilities: int naHash_size(naRef h); int naHash_get(naRef hash, naRef key, naRef* out); @@ -175,6 +253,11 @@ naRef naHash_cget(naRef hash, char* key); void naHash_set(naRef hash, naRef key, naRef val); void naHash_cset(naRef hash, char* key, naRef val); void naHash_delete(naRef hash, naRef key); +/** + * Store the keys in ::hash into the vector at ::dst + * + * @see ::naNewVector + */ void naHash_keys(naRef dst, naRef hash); // Ghost utilities: @@ -185,10 +268,29 @@ typedef struct naGhostType { void(*set_member)(naContext c, void*, naRef key, naRef val); } naGhostType; +/** + * Create a ghost for an object without any attributes. If ::t contains pointers + * to get_member or set_member function they will be ignored. + */ naRef naNewGhost(naContext c, naGhostType* t, void* ghost); +/** + * Create a ghost for an object. This version uses the get_member and set_member + * function pointers in ::t upon trying to get or set a member respectively from + * Nasal. + */ naRef naNewGhost2(naContext c, naGhostType* t, void* ghost); naGhostType* naGhost_type(naRef ghost); void* naGhost_ptr(naRef ghost); +/** + * Attach a nasal object to the given ghost. Binds the lifetime of @a data to + * the lifetime of the @a ghost. + */ +void naGhost_setData(naRef ghost, naRef data); +/** + * Retrieve the object attached to the @a ghost, previously set with + * naGhost_setData(). + */ +naRef naGhost_data(naRef ghost); int naIsGhost(naRef r); // Acquires a "modification lock" on a context, allowing the C code to