浏览代码

thread-safe macro wrappers

David Rose 16 年之前
父节点
当前提交
3e8b1c6ffd
共有 4 个文件被更改,包括 227 次插入11 次删除
  1. 59 0
      direct/src/plugin/load_plugin.cxx
  2. 12 0
      direct/src/plugin/load_plugin.h
  3. 102 0
      direct/src/plugin/p3d_plugin.cxx
  4. 54 11
      direct/src/plugin/p3d_plugin.h

+ 59 - 0
direct/src/plugin/load_plugin.cxx

@@ -41,8 +41,20 @@ P3D_instance_start_func *P3D_instance_start;
 P3D_instance_finish_func *P3D_instance_finish;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 
+P3D_object_get_type_func *P3D_object_get_type;
+P3D_object_get_bool_func *P3D_object_get_bool;
+P3D_object_get_int_func *P3D_object_get_int;
+P3D_object_get_float_func *P3D_object_get_float;
+P3D_object_get_string_func *P3D_object_get_string;
+P3D_object_get_repr_func *P3D_object_get_repr;
+P3D_object_get_property_func *P3D_object_get_property;
+P3D_object_set_property_func *P3D_object_set_property;
+P3D_object_has_method_func *P3D_object_has_method;
+P3D_object_call_func *P3D_object_call;
+P3D_object_eval_func *P3D_object_eval;
 P3D_object_incref_func *P3D_object_incref;
 P3D_object_decref_func *P3D_object_decref;
+
 P3D_make_class_definition_func *P3D_make_class_definition;
 P3D_new_undefined_object_func *P3D_new_undefined_object;
 P3D_new_none_object_func *P3D_new_none_object;
@@ -167,6 +179,17 @@ load_plugin(const string &p3d_plugin_filename) {
   P3D_instance_finish = (P3D_instance_finish_func *)get_func(module, "P3D_instance_finish");  
   P3D_instance_setup_window = (P3D_instance_setup_window_func *)get_func(module, "P3D_instance_setup_window");  
 
+  P3D_object_get_type = (P3D_object_get_type_func *)get_func(module, "P3D_object_get_type");
+  P3D_object_get_bool = (P3D_object_get_bool_func *)get_func(module, "P3D_object_get_bool");
+  P3D_object_get_int = (P3D_object_get_int_func *)get_func(module, "P3D_object_get_int");
+  P3D_object_get_float = (P3D_object_get_float_func *)get_func(module, "P3D_object_get_float");
+  P3D_object_get_string = (P3D_object_get_string_func *)get_func(module, "P3D_object_get_string");
+  P3D_object_get_repr = (P3D_object_get_repr_func *)get_func(module, "P3D_object_get_repr");
+  P3D_object_get_property = (P3D_object_get_property_func *)get_func(module, "P3D_object_get_property");
+  P3D_object_set_property = (P3D_object_set_property_func *)get_func(module, "P3D_object_set_property");
+  P3D_object_has_method = (P3D_object_has_method_func *)get_func(module, "P3D_object_has_method");
+  P3D_object_call = (P3D_object_call_func *)get_func(module, "P3D_object_call");
+  P3D_object_eval = (P3D_object_eval_func *)get_func(module, "P3D_object_eval");
   P3D_object_incref = (P3D_object_incref_func *)get_func(module, "P3D_object_incref");
   P3D_object_decref = (P3D_object_decref_func *)get_func(module, "P3D_object_decref");
   P3D_make_class_definition = (P3D_make_class_definition_func *)get_func(module, "P3D_make_class_definition");
@@ -194,8 +217,20 @@ load_plugin(const string &p3d_plugin_filename) {
       P3D_instance_finish == NULL ||
       P3D_instance_setup_window == NULL ||
 
+      P3D_object_get_type == NULL ||
+      P3D_object_get_bool == NULL ||
+      P3D_object_get_int == NULL ||
+      P3D_object_get_float == NULL ||
+      P3D_object_get_string == NULL ||
+      P3D_object_get_repr == NULL ||
+      P3D_object_get_property == NULL ||
+      P3D_object_set_property == NULL ||
+      P3D_object_has_method == NULL ||
+      P3D_object_call == NULL ||
+      P3D_object_eval == NULL ||
       P3D_object_incref == NULL ||
       P3D_object_decref == NULL ||
+
       P3D_make_class_definition == NULL ||
       P3D_new_undefined_object == NULL ||
       P3D_new_none_object == NULL ||
@@ -220,8 +255,20 @@ load_plugin(const string &p3d_plugin_filename) {
       << "\nP3D_instance_finish = " << P3D_instance_finish
       << "\nP3D_instance_setup_window = " << P3D_instance_setup_window
       
+      << "\nP3D_object_get_type = " << P3D_object_get_type
+      << "\nP3D_object_get_bool = " << P3D_object_get_bool
+      << "\nP3D_object_get_int = " << P3D_object_get_int
+      << "\nP3D_object_get_float = " << P3D_object_get_float
+      << "\nP3D_object_get_string = " << P3D_object_get_string
+      << "\nP3D_object_get_repr = " << P3D_object_get_repr
+      << "\nP3D_object_get_property = " << P3D_object_get_property
+      << "\nP3D_object_set_property = " << P3D_object_set_property
+      << "\nP3D_object_has_method = " << P3D_object_has_method
+      << "\nP3D_object_call = " << P3D_object_call
+      << "\nP3D_object_eval = " << P3D_object_eval
       << "\nP3D_object_incref = " << P3D_object_incref
       << "\nP3D_object_decref = " << P3D_object_decref
+
       << "\nP3D_make_class_definition = " << P3D_make_class_definition
       << "\nP3D_new_undefined_object = " << P3D_new_undefined_object
       << "\nP3D_new_none_object = " << P3D_new_none_object
@@ -301,8 +348,20 @@ unload_dso() {
   P3D_instance_finish = NULL;
   P3D_instance_setup_window = NULL;
 
+  P3D_object_get_type = NULL;
+  P3D_object_get_bool = NULL;
+  P3D_object_get_int = NULL;
+  P3D_object_get_float = NULL;
+  P3D_object_get_string = NULL;
+  P3D_object_get_repr = NULL;
+  P3D_object_get_property = NULL;
+  P3D_object_set_property = NULL;
+  P3D_object_has_method = NULL;
+  P3D_object_call = NULL;
+  P3D_object_eval = NULL;
   P3D_object_incref = NULL;
   P3D_object_decref = NULL;
+
   P3D_make_class_definition = NULL;
   P3D_new_undefined_object = NULL;
   P3D_new_none_object = NULL;

+ 12 - 0
direct/src/plugin/load_plugin.h

@@ -27,8 +27,20 @@ extern P3D_instance_start_func *P3D_instance_start;
 extern P3D_instance_finish_func *P3D_instance_finish;
 extern P3D_instance_setup_window_func *P3D_instance_setup_window;
 
+extern P3D_object_get_type_func *P3D_object_get_type;
+extern P3D_object_get_bool_func *P3D_object_get_bool;
+extern P3D_object_get_int_func *P3D_object_get_int;
+extern P3D_object_get_float_func *P3D_object_get_float;
+extern P3D_object_get_string_func *P3D_object_get_string;
+extern P3D_object_get_repr_func *P3D_object_get_repr;
+extern P3D_object_get_property_func *P3D_object_get_property;
+extern P3D_object_set_property_func *P3D_object_set_property;
+extern P3D_object_has_method_func *P3D_object_has_method;
+extern P3D_object_call_func *P3D_object_call;
+extern P3D_object_eval_func *P3D_object_eval;
 extern P3D_object_incref_func *P3D_object_incref;
 extern P3D_object_decref_func *P3D_object_decref;
+
 extern P3D_make_class_definition_func *P3D_make_class_definition;
 extern P3D_new_undefined_object_func *P3D_new_undefined_object;
 extern P3D_new_none_object_func *P3D_new_none_object;

+ 102 - 0
direct/src/plugin/p3d_plugin.cxx

@@ -121,6 +121,108 @@ P3D_instance_setup_window(P3D_instance *instance,
   RELEASE_LOCK(_api_lock);
 }
 
+P3D_object_type
+P3D_object_get_type(P3D_object *object) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  P3D_object_type result = P3D_OBJECT_GET_TYPE(object);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+bool
+P3D_object_get_bool(P3D_object *object) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  bool result = P3D_OBJECT_GET_BOOL(object);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+int
+P3D_object_get_int(P3D_object *object) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  int result = P3D_OBJECT_GET_INT(object);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+double
+P3D_object_get_float(P3D_object *object) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  double result = P3D_OBJECT_GET_FLOAT(object);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+int
+P3D_object_get_string(P3D_object *object, char *buffer, int buffer_size) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  int result = P3D_OBJECT_GET_STRING(object, buffer, buffer_size);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+int
+P3D_object_get_repr(P3D_object *object, char *buffer, int buffer_size) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  int result = P3D_OBJECT_GET_REPR(object, buffer, buffer_size);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+P3D_object *
+P3D_object_get_property(P3D_object *object, const char *property) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  P3D_object *result = P3D_OBJECT_GET_PROPERTY(object, property);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+bool
+P3D_object_set_property(P3D_object *object, const char *property, 
+                        P3D_object *value) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  bool result = P3D_OBJECT_SET_PROPERTY(object, property, value);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+bool
+P3D_object_has_method(P3D_object *object, const char *method_name) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  bool result = P3D_OBJECT_HAS_METHOD(object, method_name);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+P3D_object *
+P3D_object_call(P3D_object *object, const char *method_name, 
+                P3D_object *params[], int num_params) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  P3D_object *result = P3D_OBJECT_CALL(object, method_name, params, num_params);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+P3D_object *
+P3D_object_eval(P3D_object *object, const char *expression) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_api_lock);
+  P3D_object *result = P3D_OBJECT_EVAL(object, expression);
+  RELEASE_LOCK(_api_lock);
+  return result;
+}
+
+
 void 
 P3D_object_incref(P3D_object *object) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());

+ 54 - 11
direct/src/plugin/p3d_plugin.h

@@ -352,14 +352,14 @@ P3D_object_get_float_method(P3D_object *object);
 /* Get the object as a string.  This method copies the string into the
    provided buffer, and returns the actual length of the internal
    string (not counting any terminating null character).  If the
-   return value is larger than buffer_length, the string has been
+   return value is larger than buffer_size, the string has been
    truncated.  If it is equal, there is no null character written to
    the buffer (like strncpy).  You may call this method first with
-   buffer = NULL and buffer_length = 0 to return just the required
+   buffer = NULL and buffer_size = 0 to return just the required
    size of the buffer. */
 typedef int
 P3D_object_get_string_method(P3D_object *object, 
-                             char *buffer, int buffer_length);
+                             char *buffer, int buffer_size);
 
 /* As above, but instead of the literal object data, returns a
    user-friendly reprensentation of the object as a string.  For
@@ -369,7 +369,7 @@ P3D_object_get_string_method(P3D_object *object,
    Mechanically, this function works the same way as get_string(). */
 typedef int
 P3D_object_get_repr_method(P3D_object *object, 
-                           char *buffer, int buffer_length);
+                           char *buffer, int buffer_size);
 
 /* Looks up a property on the object by name, i.e. a data member or a
    method.  The return value is a new-reference P3D_object if the
@@ -446,7 +446,12 @@ struct _P3D_object {
 };
 
 /* These macros are defined for the convenience of invoking any of the
-   above method functions on an object. */
+   above method functions on an object.
+
+   CAUTION!  None of these macros are thread-safe; you may use them
+   only in a single-threaded application (or when only a single thread
+   of the application makes any calls into this API).  For thread-safe
+   variants, see the similarly-named function calls below. */
 
 #define P3D_OBJECT_GET_TYPE(object) ((object)->_class->_get_type((object)))
 #define P3D_OBJECT_GET_BOOL(object) ((object)->_class->_get_bool((object)))
@@ -458,14 +463,14 @@ struct _P3D_object {
 #define P3D_OBJECT_GET_PROPERTY(object, property) ((object)->_class->_get_property((object), (property)))
 #define P3D_OBJECT_SET_PROPERTY(object, property, value) ((object)->_class->_set_property((object), (property), (value)))
 
-#define P3D_OBJECT_HAS_METHOD(object, property) ((object)->_class->_has_method((object), (property)))
+#define P3D_OBJECT_HAS_METHOD(object, method_name) ((object)->_class->_has_method((object), (method_name)))
 #define P3D_OBJECT_CALL(object, method_name, params, num_params) ((object)->_class->_call((object), (method_name), (params), (num_params)))
 #define P3D_OBJECT_EVAL(object, expression) ((object)->_class->_eval((object), (expression)))
 
 /* These macros are provided to manipulate the reference count of the
-   indicated object.  They are not thread-safe; they should be called
-   only within the main thread.  If you need a thread-safe reference
-   count adjustment, see the similarly-named function calls below.  
+   indicated object.  As above, these macros are NOT thread-safe.  If
+   you need a thread-safe reference count adjustment, see the
+   similarly-named function calls below.
 
    Following Python's convention, XDECREF is provided to decrement the
    reference count for a pointer that might be NULL (it does nothing
@@ -475,8 +480,34 @@ struct _P3D_object {
 #define P3D_OBJECT_DECREF(object) { if (--(object)->_ref_count <= 0) { (object)->_class->_finish((object)); } }
 #define P3D_OBJECT_XDECREF(object) { if ((object) != (P3D_object *)NULL) { P3D_OBJECT_DECREF(object); } }
 
-/* Use these functions for thread-safe variants of the above.  You may
-   safely pass a NULL pointer into either; it will be ignored. */
+/* Use these functions for thread-safe variants of the above macros. */
+typedef P3D_object_type
+P3D_object_get_type_func(P3D_object *object);
+typedef bool
+P3D_object_get_bool_func(P3D_object *object);
+typedef int
+P3D_object_get_int_func(P3D_object *object);
+typedef double
+P3D_object_get_float_func(P3D_object *object);
+typedef int
+P3D_object_get_string_func(P3D_object *object, char *buffer, int buffer_size);
+typedef int
+P3D_object_get_repr_func(P3D_object *object, char *buffer, int buffer_size);
+typedef P3D_object *
+P3D_object_get_property_func(P3D_object *object, const char *property);
+typedef bool
+P3D_object_set_property_func(P3D_object *object, const char *property, 
+                             P3D_object *value);
+typedef bool
+P3D_object_has_method_func(P3D_object *object, const char *method_name);
+typedef P3D_object *
+P3D_object_call_func(P3D_object *object, const char *method_name, 
+                     P3D_object *params[], int num_params);
+typedef P3D_object *
+P3D_object_eval_func(P3D_object *object, const char *expression);
+
+/* A NULL pointer passed into either incref or decref is safe and will
+   be quietly ignored. */
 typedef void 
 P3D_object_incref_func(P3D_object *object);
 typedef void 
@@ -761,8 +792,20 @@ EXPCL_P3D_PLUGIN P3D_instance_start_func P3D_instance_start;
 EXPCL_P3D_PLUGIN P3D_instance_finish_func P3D_instance_finish;
 EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
 
+EXPCL_P3D_PLUGIN P3D_object_get_type_func P3D_object_get_type;
+EXPCL_P3D_PLUGIN P3D_object_get_bool_func P3D_object_get_bool;
+EXPCL_P3D_PLUGIN P3D_object_get_int_func P3D_object_get_int;
+EXPCL_P3D_PLUGIN P3D_object_get_float_func P3D_object_get_float;
+EXPCL_P3D_PLUGIN P3D_object_get_string_func P3D_object_get_string;
+EXPCL_P3D_PLUGIN P3D_object_get_repr_func P3D_object_get_repr;
+EXPCL_P3D_PLUGIN P3D_object_get_property_func P3D_object_get_property;
+EXPCL_P3D_PLUGIN P3D_object_set_property_func P3D_object_set_property;
+EXPCL_P3D_PLUGIN P3D_object_has_method_func P3D_object_has_method;
+EXPCL_P3D_PLUGIN P3D_object_call_func P3D_object_call;
+EXPCL_P3D_PLUGIN P3D_object_eval_func P3D_object_eval;
 EXPCL_P3D_PLUGIN P3D_object_incref_func P3D_object_incref;
 EXPCL_P3D_PLUGIN P3D_object_decref_func P3D_object_decref;
+
 EXPCL_P3D_PLUGIN P3D_make_class_definition_func P3D_make_class_definition;
 EXPCL_P3D_PLUGIN P3D_new_undefined_object_func P3D_new_undefined_object;
 EXPCL_P3D_PLUGIN P3D_new_none_object_func P3D_new_none_object;