diff --git a/src/bind/dobinding.cpp b/src/bind/dobinding.cpp
index 29da3c0a4882f093e7f655be080a61de1585d6d0..1ba708ed7c312bbcaa9209aadf062991ccf5cbc9 100644 (file)
--- a/src/bind/dobinding.cpp
+++ b/src/bind/dobinding.cpp
/**
- * This is a simple mechanism to bind Inkscape to Java, and thence
- * to all of the nice things that can be layered upon that.
+ * @file
+ * @brief This is a simple mechanism to bind Inkscape to Java, and thence
+ * to all of the nice things that can be layered upon that.
*
* Authors:
* Bob Jamison
*
- * Copyright (C) 2007 Bob Jamison
+ * Copyright (C) 2007-2008 Bob Jamison
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
+ * version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* This file can get quite large!
*/
+/**
+ * This struct associates a class name with its native
+ * bindings. Since C++ does not allow "flexible" arrays,
+ * we will separate each of the tables into a JNINativeMethod
+ * array, and a class with a name and a pointer to that array.
+ */
+typedef struct
+{
+ const char *className;
+ JNINativeMethod *methods;
+} NativeClass;
+
+/**
+ * Although I dislike macros, this one seems reasonable
+ */
+#define EXCEPTION (getExceptionString(env).c_str())
//########################################################################
//# BASE OBJECT
//########################################################################
+static jmethodID _getPointer_id = NULL;
+
static jlong getPointer(JNIEnv *env, jobject obj)
{
- jfieldID id = env->GetFieldID(env->GetObjectClass(obj), "_pointer", "J");
- jlong val = env->GetLongField(obj, id);
+ if (!_getPointer_id)
+ {
+ _getPointer_id = env->GetMethodID(env->GetObjectClass(obj), "getPointer", "()J");
+ if (!_getPointer_id)
+ {
+ err("getPointer(): %s", EXCEPTION);
+ return 0;
+ }
+ }
+ jlong val = env->CallLongMethod(obj, _getPointer_id);
return val;
}
+
+static jmethodID _setPointer_id = NULL;
+
static void setPointer(JNIEnv *env, jobject obj, jlong val)
{
- jfieldID id = env->GetFieldID(env->GetObjectClass(obj), "_pointer", "J");
- env->SetLongField(obj, id, val);
+ if (!_setPointer_id)
+ {
+ _setPointer_id = env->GetMethodID(env->GetObjectClass(obj), "setPointer", "(J)V");
+ if (!_setPointer_id)
+ {
+ err("setPointer(): %s", EXCEPTION);
+ return;
+ }
+ }
+ env->CallVoidMethod(obj, _setPointer_id, val);
+}
+
+
+static void JNICALL BaseObject_construct
+ (JNIEnv *env, jobject obj)
+{
+ setPointer(env, obj, 0L);
+}
+
+static void JNICALL BaseObject_destruct
+ (JNIEnv *env, jobject obj)
+{
+ BaseObject *ptr = (BaseObject *)getPointer(env, obj);
+ if (ptr)
+ {
+ delete ptr;
+ }
+ setPointer(env, obj, 0L);
}
+
+static JNINativeMethod nm_BaseObject[] =
+{
+{ (char *)"construct", (char *)"()V", (void *)BaseObject_construct },
+{ (char *)"destruct", (char *)"()V", (void *)BaseObject_destruct },
+{ NULL, NULL, NULL }
+};
+
+static NativeClass nc_BaseObject =
+{
+ "org/inkscape/cmn/BaseObject",
+ nm_BaseObject
+};
+
+//########################################################################
+//# BASE OBJECT
+//########################################################################
+
static void JNICALL DOMBase_construct
(JNIEnv *env, jobject obj)
{
}
-static JNINativeMethod DOMBaseMethods[] =
+static JNINativeMethod nm_DOMBase[] =
{
{ (char *)"construct", (char *)"()V", (void *)DOMBase_construct },
{ (char *)"destruct", (char *)"()V", (void *)DOMBase_destruct },
{ NULL, NULL, NULL }
};
+static NativeClass nc_DOMBase =
+{
+ "org/inkscape/dom/DOMBase",
+ nm_DOMBase
+};
+
+
//########################################################################
//# DOMImplementation
//########################################################################
-static JNINativeMethod DOMImplementationMethods[] =
+static JNINativeMethod nm_DOMImplementation[] =
{
{ (char *)"construct", (char *)"()V", (void *)DOMImplementation_nCreateDocument },
{ NULL, NULL, NULL }
};
+static NativeClass nc_DOMImplementation =
+{
+ "org/inkscape/dom/DOMImplementation",
+ nm_DOMImplementation
+};
+
//########################################################################
//# MAIN
//########################################################################
-typedef struct
-{
- const char *className;
- JNINativeMethod *methods;
-} NativeEntry;
-static NativeEntry nativeEntries[] =
+/**
+ * This is a table-of-tables, matching a class name to its
+ * table of native methods. We can probably think of a cleaner way
+ * of doing this
+ */
+static NativeClass *allClasses[] =
{
- { "org/inkscape/dom/DOMBase", DOMBaseMethods },
- { "org/inkscape/dom/DOMImplementation", DOMImplementationMethods },
- { NULL, NULL }
+ &nc_BaseObject,
+ &nc_DOMBase,
+ &nc_DOMImplementation,
+ NULL
};
bool JavaBinderyImpl::doBinding()
{
- for (NativeEntry *ne = nativeEntries ; ne->className ; ne++)
+ for (NativeClass **nc = allClasses ; *nc ; nc++)
{
- bool ret = registerNatives(ne->className, ne->methods);
+ bool ret = registerNatives((*nc)->className, (*nc)->methods);
if (!ret)
{
err("Could not bind native methods");