소스 검색

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_finish_func *P3D_instance_finish;
 P3D_instance_setup_window_func *P3D_instance_setup_window;
 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_incref_func *P3D_object_incref;
 P3D_object_decref_func *P3D_object_decref;
 P3D_object_decref_func *P3D_object_decref;
+
 P3D_make_class_definition_func *P3D_make_class_definition;
 P3D_make_class_definition_func *P3D_make_class_definition;
 P3D_new_undefined_object_func *P3D_new_undefined_object;
 P3D_new_undefined_object_func *P3D_new_undefined_object;
 P3D_new_none_object_func *P3D_new_none_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_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_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_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_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");
   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_finish == NULL ||
       P3D_instance_setup_window == 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_incref == NULL ||
       P3D_object_decref == NULL ||
       P3D_object_decref == NULL ||
+
       P3D_make_class_definition == NULL ||
       P3D_make_class_definition == NULL ||
       P3D_new_undefined_object == NULL ||
       P3D_new_undefined_object == NULL ||
       P3D_new_none_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_finish = " << P3D_instance_finish
       << "\nP3D_instance_setup_window = " << P3D_instance_setup_window
       << "\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_incref = " << P3D_object_incref
       << "\nP3D_object_decref = " << P3D_object_decref
       << "\nP3D_object_decref = " << P3D_object_decref
+
       << "\nP3D_make_class_definition = " << P3D_make_class_definition
       << "\nP3D_make_class_definition = " << P3D_make_class_definition
       << "\nP3D_new_undefined_object = " << P3D_new_undefined_object
       << "\nP3D_new_undefined_object = " << P3D_new_undefined_object
       << "\nP3D_new_none_object = " << P3D_new_none_object
       << "\nP3D_new_none_object = " << P3D_new_none_object
@@ -301,8 +348,20 @@ unload_dso() {
   P3D_instance_finish = NULL;
   P3D_instance_finish = NULL;
   P3D_instance_setup_window = 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_incref = NULL;
   P3D_object_decref = NULL;
   P3D_object_decref = NULL;
+
   P3D_make_class_definition = NULL;
   P3D_make_class_definition = NULL;
   P3D_new_undefined_object = NULL;
   P3D_new_undefined_object = NULL;
   P3D_new_none_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_finish_func *P3D_instance_finish;
 extern P3D_instance_setup_window_func *P3D_instance_setup_window;
 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_incref_func *P3D_object_incref;
 extern P3D_object_decref_func *P3D_object_decref;
 extern P3D_object_decref_func *P3D_object_decref;
+
 extern P3D_make_class_definition_func *P3D_make_class_definition;
 extern P3D_make_class_definition_func *P3D_make_class_definition;
 extern P3D_new_undefined_object_func *P3D_new_undefined_object;
 extern P3D_new_undefined_object_func *P3D_new_undefined_object;
 extern P3D_new_none_object_func *P3D_new_none_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);
   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 
 void 
 P3D_object_incref(P3D_object *object) {
 P3D_object_incref(P3D_object *object) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   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
 /* Get the object as a string.  This method copies the string into the
    provided buffer, and returns the actual length of the internal
    provided buffer, and returns the actual length of the internal
    string (not counting any terminating null character).  If the
    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
    truncated.  If it is equal, there is no null character written to
    the buffer (like strncpy).  You may call this method first with
    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. */
    size of the buffer. */
 typedef int
 typedef int
 P3D_object_get_string_method(P3D_object *object, 
 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
 /* As above, but instead of the literal object data, returns a
    user-friendly reprensentation of the object as a string.  For
    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(). */
    Mechanically, this function works the same way as get_string(). */
 typedef int
 typedef int
 P3D_object_get_repr_method(P3D_object *object, 
 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
 /* 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
    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
 /* 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_TYPE(object) ((object)->_class->_get_type((object)))
 #define P3D_OBJECT_GET_BOOL(object) ((object)->_class->_get_bool((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_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_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_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)))
 #define P3D_OBJECT_EVAL(object, expression) ((object)->_class->_eval((object), (expression)))
 
 
 /* These macros are provided to manipulate the reference count of the
 /* 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
    Following Python's convention, XDECREF is provided to decrement the
    reference count for a pointer that might be NULL (it does nothing
    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_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); } }
 #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 
 typedef void 
 P3D_object_incref_func(P3D_object *object);
 P3D_object_incref_func(P3D_object *object);
 typedef void 
 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_finish_func P3D_instance_finish;
 EXPCL_P3D_PLUGIN P3D_instance_setup_window_func P3D_instance_setup_window;
 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_incref_func P3D_object_incref;
 EXPCL_P3D_PLUGIN P3D_object_decref_func P3D_object_decref;
 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_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_undefined_object_func P3D_new_undefined_object;
 EXPCL_P3D_PLUGIN P3D_new_none_object_func P3D_new_none_object;
 EXPCL_P3D_PLUGIN P3D_new_none_object_func P3D_new_none_object;