]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/nasal.h
Nasal: support for standard bitwise operators.
[simgear.git] / simgear / nasal / nasal.h
index a7741b49639657de8885d62ebe612856b90876d7..832724471ffdd3e340945008d84204500dfde976 100644 (file)
@@ -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
@@ -99,8 +140,8 @@ void naRethrowError(naContext subc);
 // Retrieve the specified member from the object, respecting the
 // "parents" array as for "object.field".  Returns zero for missing
 // fields.
-int naMember_get(naRef obj, naRef field, naRef* out);
-int naMember_cget(naRef obj, const char* field, naRef* out);
+int naMember_get(naContext c, naRef obj, naRef field, naRef* out);
+int naMember_cget(naContext c, naRef obj, const char* field, naRef* out);
 
 // Returns a hash containing functions from the Nasal standard library
 // Useful for passing as a namespace to an initial function call
@@ -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,14 +218,33 @@ 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);
+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);
-void naVec_setsize(naRef vec, int sz);
 
 // Hash utilities:
 int naHash_size(naRef h);
@@ -175,14 +253,32 @@ 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:
 typedef struct naGhostType {
     void(*destroy)(void*);
     const char* name;
+    const char*(*get_member)(naContext c, void*, naRef key, naRef* out);
+    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);
 int          naIsGhost(naRef r);