Browse Source

beginning scriptability

David Rose 16 years ago
parent
commit
c966b5f4ed

+ 17 - 5
direct/src/plugin/Sources.pp

@@ -19,31 +19,43 @@
     p3d_lock.h p3d_plugin.h \
     p3d_lock.h p3d_plugin.h \
     p3d_plugin_config.h \
     p3d_plugin_config.h \
     p3d_plugin_common.h \
     p3d_plugin_common.h \
+    p3dBoolVariant.h \
     p3dDownload.h p3dDownload.I \
     p3dDownload.h p3dDownload.I \
     p3dFileDownload.h p3dFileDownload.I \
     p3dFileDownload.h p3dFileDownload.I \
     p3dFileParams.h p3dFileParams.I \
     p3dFileParams.h p3dFileParams.I \
+    p3dFloatVariant.h \
     p3dInstance.h p3dInstance.I \
     p3dInstance.h p3dInstance.I \
     p3dInstanceManager.h p3dInstanceManager.I \
     p3dInstanceManager.h p3dInstanceManager.I \
+    p3dIntVariant.h \
+    p3dListVariant.h \
     p3dMultifileReader.h p3dMultifileReader.I \
     p3dMultifileReader.h p3dMultifileReader.I \
     p3dPackage.h p3dPackage.I \
     p3dPackage.h p3dPackage.I \
     p3dSession.h p3dSession.I \
     p3dSession.h p3dSession.I \
     p3dSplashWindow.h p3dSplashWindow.I \
     p3dSplashWindow.h p3dSplashWindow.I \
-    p3dWindowParams.h p3dWindowParams.I \
-    p3dWinSplashWindow.h p3dWinSplashWindow.I
+    p3dStringVariant.h \
+    p3dVariant.h p3dVariant.I \
+    p3dWinSplashWindow.h p3dWinSplashWindow.I \
+    p3dWindowParams.h p3dWindowParams.I
 
 
   #define INCLUDED_SOURCES \
   #define INCLUDED_SOURCES \
     p3d_plugin.cxx \
     p3d_plugin.cxx \
+    p3dBoolVariant.cxx \
     p3dDownload.cxx \
     p3dDownload.cxx \
     p3dFileDownload.cxx \
     p3dFileDownload.cxx \
     p3dFileParams.cxx \
     p3dFileParams.cxx \
+    p3dFloatVariant.cxx \
     p3dInstance.cxx \
     p3dInstance.cxx \
     p3dInstanceManager.cxx \
     p3dInstanceManager.cxx \
+    p3dIntVariant.cxx \
+    p3dListVariant.cxx \
     p3dMultifileReader.cxx \
     p3dMultifileReader.cxx \
     p3dPackage.cxx \
     p3dPackage.cxx \
-    p3dSplashWindow.cxx \
     p3dSession.cxx \
     p3dSession.cxx \
-    p3dWindowParams.cxx \
-    p3dWinSplashWindow.cxx
+    p3dSplashWindow.cxx \
+    p3dStringVariant.cxx \
+    p3dVariant.cxx \
+    p3dWinSplashWindow.cxx \
+    p3dWindowParams.cxx
 
 
   #define INSTALL_HEADERS \
   #define INSTALL_HEADERS \
     p3d_plugin.h
     p3d_plugin.h

+ 100 - 36
direct/src/plugin/load_plugin.cxx

@@ -32,18 +32,36 @@ static const string dll_ext = ".so";
 static const string default_plugin_filename = "p3d_plugin";
 static const string default_plugin_filename = "p3d_plugin";
 
 
 P3D_initialize_func *P3D_initialize;
 P3D_initialize_func *P3D_initialize;
-P3D_free_string_func *P3D_free_string;
 P3D_new_instance_func *P3D_new_instance;
 P3D_new_instance_func *P3D_new_instance;
 P3D_instance_start_func *P3D_instance_start;
 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_instance_has_property_func *P3D_instance_has_property;
+
+P3D_variant_finish_func *P3D_variant_finish;
+P3D_variant_copy_func *P3D_variant_copy;
+P3D_new_none_variant_func *P3D_new_none_variant;
+P3D_new_bool_variant_func *P3D_new_bool_variant;
+P3D_variant_get_bool_func *P3D_variant_get_bool;
+P3D_new_int_variant_func *P3D_new_int_variant;
+P3D_variant_get_int_func *P3D_variant_get_int;
+P3D_new_float_variant_func *P3D_new_float_variant;
+P3D_variant_get_float_func *P3D_variant_get_float;
+P3D_new_string_variant_func *P3D_new_string_variant;
+P3D_variant_get_string_length_func *P3D_variant_get_string_length;
+P3D_variant_extract_string_func *P3D_variant_extract_string;
+P3D_new_list_variant_func *P3D_new_list_variant;
+P3D_variant_get_list_length_func *P3D_variant_get_list_length;
+P3D_variant_get_list_item_func *P3D_variant_get_list_item;
 P3D_instance_get_property_func *P3D_instance_get_property;
 P3D_instance_get_property_func *P3D_instance_get_property;
+P3D_instance_get_property_list_func *P3D_instance_get_property_list;
 P3D_instance_set_property_func *P3D_instance_set_property;
 P3D_instance_set_property_func *P3D_instance_set_property;
+P3D_instance_call_func *P3D_instance_call;
+
 P3D_instance_get_request_func *P3D_instance_get_request;
 P3D_instance_get_request_func *P3D_instance_get_request;
 P3D_check_request_func *P3D_check_request;
 P3D_check_request_func *P3D_check_request;
 P3D_request_finish_func *P3D_request_finish;
 P3D_request_finish_func *P3D_request_finish;
 P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream;
 P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream;
+P3D_instance_feed_value_func *P3D_instance_feed_value;
 
 
 #ifdef _WIN32
 #ifdef _WIN32
 static HMODULE module = NULL;
 static HMODULE module = NULL;
@@ -145,20 +163,7 @@ load_plugin(const string &p3d_plugin_filename) {
     return false;
     return false;
   }
   }
 
 
-  // Now get all of the function pointers.
-  P3D_initialize = (P3D_initialize_func *)GetProcAddress(module, "P3D_initialize");  
-  P3D_free_string = (P3D_free_string_func *)GetProcAddress(module, "P3D_free_string");  
-  P3D_new_instance = (P3D_new_instance_func *)GetProcAddress(module, "P3D_new_instance");  
-  P3D_instance_start = (P3D_instance_start_func *)GetProcAddress(module, "P3D_instance_start");  
-  P3D_instance_finish = (P3D_instance_finish_func *)GetProcAddress(module, "P3D_instance_finish");  
-  P3D_instance_setup_window = (P3D_instance_setup_window_func *)GetProcAddress(module, "P3D_instance_setup_window");  
-  P3D_instance_has_property = (P3D_instance_has_property_func *)GetProcAddress(module, "P3D_instance_has_property");  
-  P3D_instance_get_property = (P3D_instance_get_property_func *)GetProcAddress(module, "P3D_instance_get_property");  
-  P3D_instance_set_property = (P3D_instance_set_property_func *)GetProcAddress(module, "P3D_instance_set_property");  
-  P3D_instance_get_request = (P3D_instance_get_request_func *)GetProcAddress(module, "P3D_instance_get_request");  
-  P3D_check_request = (P3D_check_request_func *)GetProcAddress(module, "P3D_check_request");  
-  P3D_request_finish = (P3D_request_finish_func *)GetProcAddress(module, "P3D_request_finish");  
-  P3D_instance_feed_url_stream = (P3D_instance_feed_url_stream_func *)GetProcAddress(module, "P3D_instance_feed_url_stream");  
+  #define get_func GetProcAddress
 
 
 #else  // _WIN32
 #else  // _WIN32
   // Posix case.
   // Posix case.
@@ -168,38 +173,78 @@ load_plugin(const string &p3d_plugin_filename) {
     // Couldn't load the .so.
     // Couldn't load the .so.
     return false;
     return false;
   }
   }
-  
-  // Now get all of the function pointers.
-  P3D_initialize = (P3D_initialize_func *)dlsym(module, "P3D_initialize");  
-  P3D_free_string = (P3D_free_string_func *)dlsym(module, "P3D_free_string");  
-  P3D_new_instance = (P3D_new_instance_func *)dlsym(module, "P3D_new_instance");  
-  P3D_instance_start = (P3D_instance_start_func *)dlsym(module, "P3D_instance_start");  
-  P3D_instance_finish = (P3D_instance_finish_func *)dlsym(module, "P3D_instance_finish");  
-  P3D_instance_setup_window = (P3D_instance_setup_window_func *)dlsym(module, "P3D_instance_setup_window");  
-  P3D_instance_has_property = (P3D_instance_has_property_func *)dlsym(module, "P3D_instance_has_property");  
-  P3D_instance_get_property = (P3D_instance_get_property_func *)dlsym(module, "P3D_instance_get_property");  
-  P3D_instance_set_property = (P3D_instance_set_property_func *)dlsym(module, "P3D_instance_set_property");  
-  P3D_instance_get_request = (P3D_instance_get_request_func *)dlsym(module, "P3D_instance_get_request");  
-  P3D_check_request = (P3D_check_request_func *)dlsym(module, "P3D_check_request");  
-  P3D_request_finish = (P3D_request_finish_func *)dlsym(module, "P3D_request_finish");  
-  P3D_instance_feed_url_stream = (P3D_instance_feed_url_stream_func *)dlsym(module, "P3D_instance_feed_url_stream");  
+
+  #define get_func dlsym
 
 
 #endif  // _WIN32
 #endif  // _WIN32
 
 
+  // Now get all of the function pointers.
+  P3D_initialize = (P3D_initialize_func *)get_func(module, "P3D_initialize");  
+  P3D_new_instance = (P3D_new_instance_func *)get_func(module, "P3D_new_instance");  
+  P3D_instance_start = (P3D_instance_start_func *)get_func(module, "P3D_instance_start");  
+  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_variant_finish = (P3D_variant_finish_func *)get_func(module, "P3D_variant_finish");
+  P3D_variant_copy = (P3D_variant_copy_func *)get_func(module, "P3D_variant_copy");
+  P3D_new_none_variant = (P3D_new_none_variant_func *)get_func(module, "P3D_new_none_variant");
+  P3D_new_bool_variant = (P3D_new_bool_variant_func *)get_func(module, "P3D_new_bool_variant");
+  P3D_variant_get_bool = (P3D_variant_get_bool_func *)get_func(module, "P3D_variant_get_bool");
+  P3D_new_int_variant = (P3D_new_int_variant_func *)get_func(module, "P3D_new_int_variant");
+  P3D_variant_get_int = (P3D_variant_get_int_func *)get_func(module, "P3D_variant_get_int");
+  P3D_new_float_variant = (P3D_new_float_variant_func *)get_func(module, "P3D_new_float_variant");
+  P3D_variant_get_float = (P3D_variant_get_float_func *)get_func(module, "P3D_variant_get_float");
+  P3D_new_string_variant = (P3D_new_string_variant_func *)get_func(module, "P3D_new_string_variant");
+  P3D_variant_get_string_length = (P3D_variant_get_string_length_func *)get_func(module, "P3D_variant_get_string_length");
+  P3D_variant_extract_string = (P3D_variant_extract_string_func *)get_func(module, "P3D_variant_extract_string");
+  P3D_new_list_variant = (P3D_new_list_variant_func *)get_func(module, "P3D_new_list_variant");
+  P3D_variant_get_list_length = (P3D_variant_get_list_length_func *)get_func(module, "P3D_variant_get_list_length");
+  P3D_variant_get_list_item = (P3D_variant_get_list_item_func *)get_func(module, "P3D_variant_get_list_item");
+  P3D_instance_get_property = (P3D_instance_get_property_func *)get_func(module, "P3D_instance_get_property");
+  P3D_instance_get_property_list = (P3D_instance_get_property_list_func *)get_func(module, "P3D_instance_get_property_list");
+  P3D_instance_set_property = (P3D_instance_set_property_func *)get_func(module, "P3D_instance_set_property");
+  P3D_instance_call = (P3D_instance_call_func *)get_func(module, "P3D_instance_call");
+
+  P3D_instance_get_request = (P3D_instance_get_request_func *)get_func(module, "P3D_instance_get_request");  
+  P3D_check_request = (P3D_check_request_func *)get_func(module, "P3D_check_request");  
+  P3D_request_finish = (P3D_request_finish_func *)get_func(module, "P3D_request_finish");  
+  P3D_instance_feed_url_stream = (P3D_instance_feed_url_stream_func *)get_func(module, "P3D_instance_feed_url_stream");  
+  P3D_instance_feed_value = (P3D_instance_feed_value_func *)get_func(module, "P3D_instance_feed_value");  
+
+  #undef get_func
+
   // Ensure that all of the function pointers have been found.
   // Ensure that all of the function pointers have been found.
   if (P3D_initialize == NULL ||
   if (P3D_initialize == NULL ||
-      P3D_free_string == NULL ||
       P3D_new_instance == NULL ||
       P3D_new_instance == NULL ||
       P3D_instance_start == NULL ||
       P3D_instance_start == NULL ||
       P3D_instance_finish == NULL ||
       P3D_instance_finish == NULL ||
       P3D_instance_setup_window == NULL ||
       P3D_instance_setup_window == NULL ||
-      P3D_instance_has_property == NULL ||
+
+      P3D_variant_finish == NULL ||
+      P3D_variant_copy == NULL ||
+      P3D_new_none_variant == NULL ||
+      P3D_new_bool_variant == NULL ||
+      P3D_variant_get_bool == NULL ||
+      P3D_new_int_variant == NULL ||
+      P3D_variant_get_int == NULL ||
+      P3D_new_float_variant == NULL ||
+      P3D_variant_get_float == NULL ||
+      P3D_new_string_variant == NULL ||
+      P3D_variant_get_string_length == NULL ||
+      P3D_variant_extract_string == NULL ||
+      P3D_new_list_variant == NULL ||
+      P3D_variant_get_list_length == NULL ||
+      P3D_variant_get_list_item == NULL ||
       P3D_instance_get_property == NULL ||
       P3D_instance_get_property == NULL ||
+      P3D_instance_get_property_list == NULL ||
       P3D_instance_set_property == NULL ||
       P3D_instance_set_property == NULL ||
+      P3D_instance_call == NULL ||
+      
       P3D_instance_get_request == NULL ||
       P3D_instance_get_request == NULL ||
       P3D_check_request == NULL ||
       P3D_check_request == NULL ||
       P3D_request_finish == NULL ||
       P3D_request_finish == NULL ||
-      P3D_instance_feed_url_stream == NULL) {
+      P3D_instance_feed_url_stream == NULL ||
+      P3D_instance_feed_value == NULL) {
     return false;
     return false;
   }
   }
 
 
@@ -239,17 +284,36 @@ unload_plugin() {
 #endif
 #endif
   
   
   P3D_initialize = NULL;
   P3D_initialize = NULL;
-  P3D_free_string = NULL;
   P3D_new_instance = NULL;
   P3D_new_instance = NULL;
   P3D_instance_start = NULL;
   P3D_instance_start = NULL;
   P3D_instance_finish = NULL;
   P3D_instance_finish = NULL;
-  P3D_instance_has_property = NULL;
+  P3D_instance_setup_window = NULL;
+
+  P3D_variant_finish = NULL;
+  P3D_variant_copy = NULL;
+  P3D_new_none_variant = NULL;
+  P3D_new_bool_variant = NULL;
+  P3D_variant_get_bool = NULL;
+  P3D_new_int_variant = NULL;
+  P3D_variant_get_int = NULL;
+  P3D_new_float_variant = NULL;
+  P3D_variant_get_float = NULL;
+  P3D_new_string_variant = NULL;
+  P3D_variant_get_string_length = NULL;
+  P3D_variant_extract_string = NULL;
+  P3D_new_list_variant = NULL;
+  P3D_variant_get_list_length = NULL;
+  P3D_variant_get_list_item = NULL;
   P3D_instance_get_property = NULL;
   P3D_instance_get_property = NULL;
+  P3D_instance_get_property_list = NULL;
   P3D_instance_set_property = NULL;
   P3D_instance_set_property = NULL;
+  P3D_instance_call = NULL;
+
   P3D_instance_get_request = NULL;
   P3D_instance_get_request = NULL;
   P3D_check_request = NULL;
   P3D_check_request = NULL;
   P3D_request_finish = NULL;
   P3D_request_finish = NULL;
   P3D_instance_feed_url_stream = NULL;
   P3D_instance_feed_url_stream = NULL;
+  P3D_instance_feed_value = NULL;
 
 
   plugin_loaded = false;
   plugin_loaded = false;
 }
 }

+ 21 - 3
direct/src/plugin/load_plugin.h

@@ -21,18 +21,36 @@
 using namespace std;
 using namespace std;
 
 
 extern P3D_initialize_func *P3D_initialize;
 extern P3D_initialize_func *P3D_initialize;
-extern P3D_free_string_func *P3D_free_string;
 extern P3D_new_instance_func *P3D_new_instance;
 extern P3D_new_instance_func *P3D_new_instance;
 extern P3D_instance_start_func *P3D_instance_start;
 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_instance_has_property_func *P3D_instance_has_property;
+
+extern P3D_variant_finish_func *P3D_variant_finish;
+extern P3D_variant_copy_func *P3D_variant_copy;
+extern P3D_new_none_variant_func *P3D_new_none_variant;
+extern P3D_new_bool_variant_func *P3D_new_bool_variant;
+extern P3D_variant_get_bool_func *P3D_variant_get_bool;
+extern P3D_new_int_variant_func *P3D_new_int_variant;
+extern P3D_variant_get_int_func *P3D_variant_get_int;
+extern P3D_new_float_variant_func *P3D_new_float_variant;
+extern P3D_variant_get_float_func *P3D_variant_get_float;
+extern P3D_new_string_variant_func *P3D_new_string_variant;
+extern P3D_variant_get_string_length_func *P3D_variant_get_string_length;
+extern P3D_variant_extract_string_func *P3D_variant_extract_string;
+extern P3D_new_list_variant_func *P3D_new_list_variant;
+extern P3D_variant_get_list_length_func *P3D_variant_get_list_length;
+extern P3D_variant_get_list_item_func *P3D_variant_get_list_item;
 extern P3D_instance_get_property_func *P3D_instance_get_property;
 extern P3D_instance_get_property_func *P3D_instance_get_property;
+extern P3D_instance_get_property_list_func *P3D_instance_get_property_list;
 extern P3D_instance_set_property_func *P3D_instance_set_property;
 extern P3D_instance_set_property_func *P3D_instance_set_property;
-extern P3D_instance_get_request_func *P3D_instance_get_request;
+extern P3D_instance_call_func *P3D_instance_call;
+
+extern P3D_instance_get_request_func *P3D_get_request;
 extern P3D_check_request_func *P3D_check_request;
 extern P3D_check_request_func *P3D_check_request;
 extern P3D_request_finish_func *P3D_request_finish;
 extern P3D_request_finish_func *P3D_request_finish;
 extern P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream;
 extern P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream;
+extern P3D_instance_feed_value_func *P3D_instance_feed_value;
 
 
 string get_plugin_basename();
 string get_plugin_basename();
 bool load_plugin(const string &p3d_plugin_filename);
 bool load_plugin(const string &p3d_plugin_filename);

+ 87 - 0
direct/src/plugin/p3dBoolVariant.cxx

@@ -0,0 +1,87 @@
+// Filename: p3dBoolVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dBoolVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DBoolVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DBoolVariant::
+P3DBoolVariant(bool value) : 
+  P3DVariant(P3D_VT_bool),
+  _value(value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DBoolVariant::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DBoolVariant::
+P3DBoolVariant(const P3DBoolVariant &copy) :
+  P3DVariant(copy),
+  _value(copy._value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DBoolVariant::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DBoolVariant::
+make_copy() {
+  return new P3DBoolVariant(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DBoolVariant::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DBoolVariant::
+get_bool() const {
+  return _value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DBoolVariant::get_int
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to an integer, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+int P3DBoolVariant::
+get_int() const {
+  return _value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DBoolVariant::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DBoolVariant::
+make_string(string &value) const {
+  if (_value) {
+    value = "1";
+  } else {
+    value = "0";
+  }
+}
+

+ 41 - 0
direct/src/plugin/p3dBoolVariant.h

@@ -0,0 +1,41 @@
+// Filename: p3dBoolVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DBOOLVARIANT_H
+#define P3DBOOLVARIANT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DBoolVariant
+// Description : A variant type that contains a boolean value.
+////////////////////////////////////////////////////////////////////
+class P3DBoolVariant : public P3DVariant {
+public:
+  P3DBoolVariant(bool value);
+  P3DBoolVariant(const P3DBoolVariant &copy);
+
+public:
+  virtual P3DVariant *make_copy(); 
+  virtual bool get_bool() const;
+  virtual int get_int() const;
+  virtual void make_string(string &value) const;
+
+private:
+  bool _value;
+};
+
+#endif
+

+ 96 - 0
direct/src/plugin/p3dFloatVariant.cxx

@@ -0,0 +1,96 @@
+// Filename: p3dFloatVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dFloatVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DFloatVariant::
+P3DFloatVariant(double value) : 
+  P3DVariant(P3D_VT_float),
+  _value(value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DFloatVariant::
+P3DFloatVariant(const P3DFloatVariant &copy) :
+  P3DVariant(copy),
+  _value(copy._value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DFloatVariant::
+make_copy() {
+  return new P3DFloatVariant(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DFloatVariant::
+get_bool() const {
+  return (_value != 0.0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::get_int
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to an integer, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+int P3DFloatVariant::
+get_int() const {
+  return (int)_value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::get_float
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a floating-point
+//               value, if possible.
+////////////////////////////////////////////////////////////////////
+double P3DFloatVariant::
+get_float() const {
+  return _value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DFloatVariant::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DFloatVariant::
+make_string(string &value) const {
+  ostringstream strm;
+  strm << _value;
+  value = strm.str();
+}
+

+ 42 - 0
direct/src/plugin/p3dFloatVariant.h

@@ -0,0 +1,42 @@
+// Filename: p3dFloatVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DFLOATVARIANT_H
+#define P3DFLOATVARIANT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DFloatVariant
+// Description : A variant type that contains a floating-point value.
+////////////////////////////////////////////////////////////////////
+class P3DFloatVariant : public P3DVariant {
+public:
+  P3DFloatVariant(double value);
+  P3DFloatVariant(const P3DFloatVariant &copy);
+
+public:
+  virtual P3DVariant *make_copy(); 
+  virtual bool get_bool() const;
+  virtual int get_int() const;
+  virtual double get_float() const;
+  virtual void make_string(string &value) const;
+
+private:
+  double _value;
+};
+
+#endif
+

+ 53 - 24
direct/src/plugin/p3dInstance.cxx

@@ -19,6 +19,8 @@
 #include "p3dPackage.h"
 #include "p3dPackage.h"
 #include "p3dSplashWindow.h"
 #include "p3dSplashWindow.h"
 #include "p3dWinSplashWindow.h"
 #include "p3dWinSplashWindow.h"
+#include "p3dVariant.h"
+#include "p3dNoneVariant.h"
 
 
 #include <sstream>
 #include <sstream>
 #include <algorithm>
 #include <algorithm>
@@ -157,41 +159,54 @@ set_wparams(const P3DWindowParams &wparams) {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: P3DInstance::has_property
+//     Function: P3DInstance::get_property
 //       Access: Public
 //       Access: Public
-//  Description: Returns true if the instance has the named property,
-//               false otherwise.
-////////////////////////////////////////////////////////////////////
-bool P3DInstance::
-has_property(const string &property_name) const {
-  return false;
+//  Description: Returns the value of the named property, or NULL
+//               if there is no such property.  Properties are created
+//               by the script run within the instance; they are used
+//               for communicating between scripting languages (for
+//               instance, communication between the Python-based
+//               Panda application, and the Javascript on the
+//               containing web page).
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DInstance::
+get_property(const string &property_name) const {
+  return NULL;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: P3DInstance::get_property
+//     Function: P3DInstance::get_property_list
 //       Access: Public
 //       Access: Public
-//  Description: Returns the value of the named property, or empty
-//               string if there is no such property.  Properties are
-//               created by the script run within the instance; they
-//               are used for communicating between scripting
-//               languages (for instance, communication between the
-//               Python-based Panda application, and the Javascript on
-//               the containing web page).
-////////////////////////////////////////////////////////////////////
-string P3DInstance::
-get_property(const string &property_name) const {
-  return string();
+//  Description: Returns a list of subordinate properties below the
+//               named property.
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DInstance::
+get_property_list(const string &property_name) const {
+  return NULL;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstance::set_property
 //     Function: P3DInstance::set_property
 //       Access: Public
 //       Access: Public
-//  Description: Changes the value of the named property.  It is an
-//               error to call this on a property that does not
-//               already exist.
+//  Description: Changes the value of the named property, or deletes
+//               it if value is NULL.  If the named property does not
+//               already exist, creates it.  Returns true on success,
+//               false on failure.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-void P3DInstance::
-set_property(const string &property_name, const string &value) {
+bool P3DInstance::
+set_property(const string &property_name, const P3DVariant *value) {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::call
+//       Access: Public
+//  Description: Calls the named property as a method, supplying the
+//               indicated parameters.
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DInstance::
+call(const string &property_name, const P3DVariant *params) {
+  return new P3DNoneVariant;
 }
 }
 
 
 
 
@@ -330,6 +345,20 @@ feed_url_stream(int unique_id,
   return download_ok;
   return download_ok;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::feed_value
+//       Access: Public
+//  Description: Called by the host in response to a get_property or
+//               call request.  The value object must have been
+//               freshly allocated; it will be deleted by this method.
+////////////////////////////////////////////////////////////////////
+void P3DInstance::
+feed_value(int unique_id, P3DVariant *variant) {
+  if (variant != NULL) {
+    delete variant;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstance::add_package
 //     Function: P3DInstance::add_package
 //       Access: Public
 //       Access: Public

+ 7 - 3
direct/src/plugin/p3dInstance.h

@@ -28,6 +28,7 @@ class P3DSession;
 class P3DSplashWindow;
 class P3DSplashWindow;
 class P3DDownload;
 class P3DDownload;
 class P3DPackage;
 class P3DPackage;
+class P3DVariant;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : P3DInstance
 //       Class : P3DInstance
@@ -45,9 +46,11 @@ public:
   void set_wparams(const P3DWindowParams &wparams);
   void set_wparams(const P3DWindowParams &wparams);
   inline const P3DWindowParams &get_wparams() const;
   inline const P3DWindowParams &get_wparams() const;
 
 
-  bool has_property(const string &property_name) const;
-  string get_property(const string &property_name) const;
-  void set_property(const string &property_name, const string &value);
+  P3DVariant *get_property(const string &property_name) const;
+  P3DVariant *get_property_list(const string &property_name) const;
+  bool set_property(const string &property_name, 
+                    const P3DVariant *value);
+  P3DVariant *call(const string &property_name, const P3DVariant *params);
 
 
   bool has_request();
   bool has_request();
   P3D_request *get_request();
   P3D_request *get_request();
@@ -60,6 +63,7 @@ public:
                        size_t total_expected_data,
                        size_t total_expected_data,
                        const unsigned char *this_data, 
                        const unsigned char *this_data, 
                        size_t this_data_size);
                        size_t this_data_size);
+  void feed_value(int unique_id, P3DVariant *value);
 
 
   inline int get_instance_id() const;
   inline int get_instance_id() const;
   inline const string &get_session_key() const;
   inline const string &get_session_key() const;

+ 85 - 0
direct/src/plugin/p3dIntVariant.cxx

@@ -0,0 +1,85 @@
+// Filename: p3dIntVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dIntVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DIntVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DIntVariant::
+P3DIntVariant(int value) : 
+  P3DVariant(P3D_VT_int),
+  _value(value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DIntVariant::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DIntVariant::
+P3DIntVariant(const P3DIntVariant &copy) :
+  P3DVariant(copy),
+  _value(copy._value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DIntVariant::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DIntVariant::
+make_copy() {
+  return new P3DIntVariant(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DIntVariant::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DIntVariant::
+get_bool() const {
+  return (_value != 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DIntVariant::get_int
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to an integer, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+int P3DIntVariant::
+get_int() const {
+  return _value;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DIntVariant::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DIntVariant::
+make_string(string &value) const {
+  ostringstream strm;
+  strm << _value;
+  value = strm.str();
+}
+

+ 41 - 0
direct/src/plugin/p3dIntVariant.h

@@ -0,0 +1,41 @@
+// Filename: p3dIntVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DINTVARIANT_H
+#define P3DINTVARIANT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DIntVariant
+// Description : A variant type that contains an integer value.
+////////////////////////////////////////////////////////////////////
+class P3DIntVariant : public P3DVariant {
+public:
+  P3DIntVariant(int value);
+  P3DIntVariant(const P3DIntVariant &copy);
+
+public:
+  virtual P3DVariant *make_copy(); 
+  virtual bool get_bool() const;
+  virtual int get_int() const;
+  virtual void make_string(string &value) const;
+
+private:
+  int _value;
+};
+
+#endif
+

+ 130 - 0
direct/src/plugin/p3dListVariant.cxx

@@ -0,0 +1,130 @@
+// Filename: p3dListVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dListVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DListVariant::
+P3DListVariant(P3DVariant * const elements[], int num_elements) :
+  P3DVariant(P3D_VT_list)
+{
+  _elements.reserve(num_elements);
+  for (int i = 0; i < num_elements; ++i) {
+    _elements.push_back(elements[i]);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DListVariant::
+P3DListVariant(const P3DListVariant &copy) :
+  P3DVariant(copy)
+{
+  _elements.reserve(copy._elements.size());
+  Elements::const_iterator ei;
+  for (ei = copy._elements.begin(); ei != copy._elements.end(); ++ei) {
+    _elements.push_back((*ei)->make_copy());
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::Destructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DListVariant::
+~P3DListVariant() {
+  Elements::iterator ei;
+  for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
+    delete (*ei);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DListVariant::
+make_copy() {
+  return new P3DListVariant(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DListVariant::
+get_bool() const {
+  return !_elements.empty();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DListVariant::
+make_string(string &value) const {
+  ostringstream strm;
+  strm << "[";
+  if (!_elements.empty()) {
+    string es;
+    _elements[0]->make_string(es);
+    strm << es;
+    for (size_t i = 1; i < _elements.size(); ++i) {
+      _elements[0]->make_string(es);
+      strm << ", " << es;
+    }
+  }
+  strm << "]";
+
+  value = strm.str();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::get_list_length
+//       Access: Public, Virtual
+//  Description: Returns the length of the variant value as a list.
+////////////////////////////////////////////////////////////////////
+int P3DListVariant::
+get_list_length() const {
+  return _elements.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DListVariant::get_list_item
+//       Access: Public, Virtual
+//  Description: Returns the nth item in the variant as a list.  The
+//               return value is a freshly-allocated P3DVariant object
+//               that must be deleted by the caller, or NULL on error.
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DListVariant::
+get_list_item(int n) const {
+  if (n >= 0 && n < (int)_elements.size()) {
+    return _elements[n]->make_copy();
+  }
+
+  return NULL;
+}

+ 45 - 0
direct/src/plugin/p3dListVariant.h

@@ -0,0 +1,45 @@
+// Filename: p3dListVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DLISTVARIANT_H
+#define P3DLISTVARIANT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DListVariant
+// Description : A variant type that contains a list of other variants.
+////////////////////////////////////////////////////////////////////
+class P3DListVariant : public P3DVariant {
+public:
+  P3DListVariant(P3DVariant * const elements[], int num_elements);
+  P3DListVariant(const P3DListVariant &copy);
+
+public:
+  virtual ~P3DListVariant();
+
+  virtual P3DVariant *make_copy(); 
+  virtual bool get_bool() const;
+  virtual void make_string(string &value) const;
+  virtual int get_list_length() const;
+  virtual P3DVariant *get_list_item(int n) const;
+
+private:
+  typedef vector<P3DVariant *> Elements;
+  Elements _elements;
+};
+
+#endif
+

+ 56 - 0
direct/src/plugin/p3dNoneVariant.cxx

@@ -0,0 +1,56 @@
+// Filename: p3dNoneVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dNoneVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNoneVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DNoneVariant::
+P3DNoneVariant() : P3DVariant(P3D_VT_none) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNoneVariant::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DNoneVariant::
+make_copy() {
+  return new P3DNoneVariant(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNoneVariant::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DNoneVariant::
+get_bool() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DNoneVariant::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DNoneVariant::
+make_string(string &value) const {
+  value = "None";
+}

+ 37 - 0
direct/src/plugin/p3dNoneVariant.h

@@ -0,0 +1,37 @@
+// Filename: p3dNoneVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DNONEVARIANT_H
+#define P3DNONEVARIANT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DNoneVariant
+// Description : A variant type that contains no value, similar to
+//               Python's None type.
+////////////////////////////////////////////////////////////////////
+class P3DNoneVariant : public P3DVariant {
+public:
+  P3DNoneVariant();
+
+public:
+  virtual P3DVariant *make_copy();
+  virtual bool get_bool() const;
+  virtual void make_string(string &value) const;
+};
+
+#endif
+

+ 81 - 0
direct/src/plugin/p3dStringVariant.cxx

@@ -0,0 +1,81 @@
+// Filename: p3dStringVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dStringVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DStringVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DStringVariant::
+P3DStringVariant(const char *value, int length) : 
+  P3DVariant(P3D_VT_string),
+  _value(value, length)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DStringVariant::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DStringVariant::
+P3DStringVariant(const P3DStringVariant &copy) :
+  P3DVariant(copy),
+  _value(copy._value)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DStringVariant::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DStringVariant::
+~P3DStringVariant() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DStringVariant::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DStringVariant::
+make_copy() {
+  return new P3DStringVariant(*this);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DStringVariant::get_bool
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a boolean, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+bool P3DStringVariant::
+get_bool() const {
+  return !_value.empty();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DStringVariant::make_string
+//       Access: Public, Virtual
+//  Description: Fills the indicated C++ string object with the value
+//               of this object coerced to a string.
+////////////////////////////////////////////////////////////////////
+void P3DStringVariant::
+make_string(string &value) const {
+  value = _value;
+}
+

+ 42 - 0
direct/src/plugin/p3dStringVariant.h

@@ -0,0 +1,42 @@
+// Filename: p3dStringVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DSTRINGVARIANT_H
+#define P3DSTRINGVARIANT_H
+
+#include "p3d_plugin_common.h"
+#include "p3dVariant.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DStringVariant
+// Description : A variant type that contains a string value.
+////////////////////////////////////////////////////////////////////
+class P3DStringVariant : public P3DVariant {
+public:
+  P3DStringVariant(const char *value, int length);
+  P3DStringVariant(const P3DStringVariant &copy);
+
+public:
+  virtual ~P3DStringVariant();
+
+  virtual P3DVariant *make_copy(); 
+  virtual bool get_bool() const;
+  virtual void make_string(string &value) const;
+
+private:
+  string _value;
+};
+
+#endif
+

+ 34 - 0
direct/src/plugin/p3dVariant.I

@@ -0,0 +1,34 @@
+// Filename: p3dVariant.I
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+inline P3DVariant::
+P3DVariant(P3D_variant_type type) {
+  _type = type;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+inline P3DVariant::
+P3DVariant(const P3DVariant &copy) {
+  _type = copy._type;
+}

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

@@ -0,0 +1,102 @@
+// Filename: p3dVariant.cxx
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "p3dVariant.h"
+#include <string.h>  // memcpy
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+P3DVariant::
+~P3DVariant() {
+  _type = P3D_VT_none;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::get_int
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to an integer, if
+//               possible.
+////////////////////////////////////////////////////////////////////
+int P3DVariant::
+get_int() const {
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::get_float
+//       Access: Public, Virtual
+//  Description: Returns the variant value coerced to a floating-point
+//               value, if possible.
+////////////////////////////////////////////////////////////////////
+double P3DVariant::
+get_float() const {
+  return get_int();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::get_string_length
+//       Access: Public, Virtual
+//  Description: Returns the length of the string that represents the
+//               variant value, not counting any null termination
+//               characters.
+////////////////////////////////////////////////////////////////////
+int P3DVariant::
+get_string_length() const {
+  string result;
+  make_string(result);
+  return result.length();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::extract_string
+//       Access: Public, Virtual
+//  Description: Stores a string that represents the variant value in
+//               the indicated buffer; a null character is included if
+//               there is space.  Returns the number of characters
+//               needed in the output (which might be more than the
+//               actual number of characters stored if buffer_length
+//               was too small).
+////////////////////////////////////////////////////////////////////
+int P3DVariant::
+extract_string(char *buffer, int buffer_length) const {
+  string result;
+  make_string(result);
+  memcpy(buffer, result.c_str(), min(buffer_length, (int)result.size() + 1));
+  return (int)result.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::get_list_length
+//       Access: Public, Virtual
+//  Description: Returns the length of the variant value as a list.
+////////////////////////////////////////////////////////////////////
+int P3DVariant::
+get_list_length() const {
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DVariant::get_list_item
+//       Access: Public, Virtual
+//  Description: Returns the nth item in the variant as a list.  The
+//               return value is a freshly-allocated P3DVariant object
+//               that must be deleted by the caller, or NULL on error.
+////////////////////////////////////////////////////////////////////
+P3DVariant *P3DVariant::
+get_list_item(int n) const {
+  return NULL;
+}

+ 52 - 0
direct/src/plugin/p3dVariant.h

@@ -0,0 +1,52 @@
+// Filename: p3dVariant.h
+// Created by:  drose (30Jun09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef P3DVARIANT_H
+#define P3DVARIANT_H
+
+#include "p3d_plugin_common.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : P3DVariant
+// Description : The C++ implementation of P3D_variant, corresponding
+//               to a single atomic value that is passed around
+//               between scripting languages.  This is an abstract
+//               base class; the actual implementations are provided
+//               by the various specialized classes, below.
+////////////////////////////////////////////////////////////////////
+class P3DVariant : public P3D_variant {
+protected:
+  inline P3DVariant(P3D_variant_type type);
+  inline P3DVariant(const P3DVariant &copy);
+
+public:
+  virtual ~P3DVariant();
+
+  virtual P3DVariant *make_copy()=0; 
+  virtual bool get_bool() const=0;
+  virtual int get_int() const;
+  virtual double get_float() const;
+
+  int get_string_length() const;
+  int extract_string(char *buffer, int buffer_length) const;
+  virtual void make_string(string &value) const=0;
+
+  virtual int get_list_length() const;
+  virtual P3DVariant *get_list_item(int n) const;
+};
+
+#include "p3dVariant.I"
+
+#endif
+

+ 172 - 21
direct/src/plugin/p3d_plugin.cxx

@@ -16,6 +16,12 @@
 #include "p3dInstanceManager.h"
 #include "p3dInstanceManager.h"
 #include "p3dInstance.h"
 #include "p3dInstance.h"
 #include "p3dWindowParams.h"
 #include "p3dWindowParams.h"
+#include "p3dNoneVariant.h"
+#include "p3dBoolVariant.h"
+#include "p3dIntVariant.h"
+#include "p3dFloatVariant.h"
+#include "p3dStringVariant.h"
+#include "p3dListVariant.h"
 
 
 #include <assert.h>
 #include <assert.h>
 
 
@@ -61,13 +67,6 @@ P3D_initialize(int api_version, const char *output_filename) {
   return result;
   return result;
 }
 }
 
 
-void 
-P3D_free_string(char *string) {
-  ACQUIRE_LOCK(_lock);
-  delete [] string;
-  RELEASE_LOCK(_lock);
-}
-
 P3D_instance *
 P3D_instance *
 P3D_new_instance(P3D_request_ready_func *func, void *user_data) {
 P3D_new_instance(P3D_request_ready_func *func, void *user_data) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
@@ -117,41 +116,185 @@ P3D_instance_setup_window(P3D_instance *instance,
   RELEASE_LOCK(_lock);
   RELEASE_LOCK(_lock);
 }
 }
 
 
+void 
+P3D_variant_finish(P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  delete (P3DVariant *)variant;
+  RELEASE_LOCK(_lock);
+}
+
+P3D_variant *
+P3D_variant_copy(const P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = ((P3DVariant *)variant)->make_copy();
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_new_none_variant() {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = new P3DNoneVariant();
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_new_bool_variant(bool value) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = new P3DBoolVariant(value);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
 bool
 bool
-P3D_instance_has_property(P3D_instance *instance,
-                          const char *property_name) {
+P3D_variant_get_bool(const P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  bool result = ((const P3DVariant *)variant)->get_bool();
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_new_int_variant(int value) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = new P3DIntVariant(value);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+int
+P3D_variant_get_int(const P3D_variant *variant) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   ACQUIRE_LOCK(_lock);
   ACQUIRE_LOCK(_lock);
-  bool result = ((P3DInstance *)instance)->has_property(property_name);
+  int result = ((const P3DVariant *)variant)->get_int();
   RELEASE_LOCK(_lock);
   RELEASE_LOCK(_lock);
   return result;
   return result;
 }
 }
 
 
-char *
-P3D_instance_get_property(P3D_instance *instance,
+P3D_variant *
+P3D_new_float_variant(double value) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = new P3DFloatVariant(value);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+double
+P3D_variant_get_float(const P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  double result = ((const P3DVariant *)variant)->get_float();
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_new_string_variant(const char *value, int length) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = new P3DStringVariant(value, length);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+int
+P3D_variant_get_string_length(const P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  int result = ((const P3DVariant *)variant)->get_string_length();
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+int
+P3D_variant_extract_string(const P3D_variant *variant, char *buffer, 
+                           int buffer_length) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  int result = 
+    ((const P3DVariant *)variant)->extract_string(buffer, buffer_length);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_new_list_variant(P3D_variant * const elements[], int num_elements) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = new P3DListVariant((P3DVariant * const *)elements, num_elements);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+int
+P3D_variant_get_list_length(const P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  int result = ((const P3DVariant *)variant)->get_list_length();
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_variant_get_list_item(const P3D_variant *variant, int n) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = ((const P3DVariant *)variant)->get_list_item(n);
+  RELEASE_LOCK(_lock);
+  return result;
+}
+
+P3D_variant *
+P3D_instance_get_property(const P3D_instance *instance, 
                           const char *property_name) {
                           const char *property_name) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   ACQUIRE_LOCK(_lock);
   ACQUIRE_LOCK(_lock);
-  string value = ((P3DInstance *)instance)->get_property(property_name);
+  P3D_variant *result = ((const P3DInstance *)instance)->get_property(property_name);
+  RELEASE_LOCK(_lock);
+  return result;
+}
 
 
-  char *result = new char[value.length() + 1];
+P3D_variant *
+P3D_instance_get_property_list(const P3D_instance *instance, 
+                               const char *property_name) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  P3D_variant *result = ((const P3DInstance *)instance)->get_property_list(property_name);
   RELEASE_LOCK(_lock);
   RELEASE_LOCK(_lock);
+  return result;
+}
 
 
-  memcpy(result, value.data(), value.length());
-  result[value.length()] = '\0';
+bool
+P3D_instance_set_property(P3D_instance *instance, const char *property_name,
+                          const P3D_variant *value) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  bool result = 
+    ((P3DInstance *)instance)->set_property(property_name, (const P3DVariant *)value);
+  RELEASE_LOCK(_lock);
   return result;
   return result;
 }
 }
 
 
-void 
-P3D_instance_set_property(P3D_instance *instance,
-                          const char *property_name,
-                          const char *value) {
+P3D_variant *
+P3D_instance_call(P3D_instance *instance, const char *property_name,
+                  const P3D_variant *params) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   ACQUIRE_LOCK(_lock);
   ACQUIRE_LOCK(_lock);
-  ((P3DInstance *)instance)->set_property(property_name, value);
+  P3D_variant *result = 
+    ((P3DInstance *)instance)->call(property_name, (P3DVariant *)params);
   RELEASE_LOCK(_lock);
   RELEASE_LOCK(_lock);
+  return result;
 }
 }
 
 
+
 P3D_request *
 P3D_request *
 P3D_instance_get_request(P3D_instance *instance) {
 P3D_instance_get_request(P3D_instance *instance) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
@@ -212,3 +355,11 @@ P3D_instance_feed_url_stream(P3D_instance *instance, int unique_id,
   return result;
   return result;
 }
 }
 
 
+void
+P3D_instance_feed_value(P3D_instance *instance, int unique_id,
+                        P3D_variant *variant) {
+  assert(P3DInstanceManager::get_global_ptr()->is_initialized());
+  ACQUIRE_LOCK(_lock);
+  ((P3DInstance *)instance)->feed_value(unique_id, (P3DVariant *)variant);
+  RELEASE_LOCK(_lock);
+}

+ 232 - 28
direct/src/plugin/p3d_plugin.h

@@ -73,7 +73,7 @@ extern "C" {
 libraries match.  It should be passed to P3D_initialize() (below).
 libraries match.  It should be passed to P3D_initialize() (below).
 This number will be incremented whenever there are changes to any of
 This number will be incremented whenever there are changes to any of
 the interface specifications defined in this header file. */
 the interface specifications defined in this header file. */
-#define P3D_API_VERSION 2
+#define P3D_API_VERSION 3
 
 
 /************************ GLOBAL FUNCTIONS **************************/
 /************************ GLOBAL FUNCTIONS **************************/
 
 
@@ -97,12 +97,6 @@ the interface specifications defined in this header file. */
 typedef bool 
 typedef bool 
 P3D_initialize_func(int api_version, const char *output_filename);
 P3D_initialize_func(int api_version, const char *output_filename);
 
 
-/* This function frees a pointer returned by
-   P3D_instance_get_property(), or another similar function that
-   returns a dynamically-allocated string. */
-typedef void 
-P3D_free_string_func(char *string);
-
 /********************** INSTANCE MANAGEMENT **************************/
 /********************** INSTANCE MANAGEMENT **************************/
 
 
 /* The following interfaces define the API to manage individual
 /* The following interfaces define the API to manage individual
@@ -269,27 +263,162 @@ P3D_instance_setup_window_func(P3D_instance *instance,
 /* The following interfaces are provided to support controlling the
 /* The following interfaces are provided to support controlling the
    plugin via JavaScript or related interfaces on the browser. */
    plugin via JavaScript or related interfaces on the browser. */
 
 
-/* Call this function to query whether the instance has a property of
-   the indicated name.  If this returns true, you may then query
-   P3D_instance_get_property() or P3D_instance_set_property(). */
-typedef bool
-P3D_instance_has_property_func(P3D_instance *instance,
-                               const char *property_name);
+/* This enumeration indicates which fundamental type is represented by
+   a particular P3D_variant object, below. */
+typedef enum {
+  P3D_VT_none,
+  P3D_VT_bool,
+  P3D_VT_int,
+  P3D_VT_float,
+  P3D_VT_string,
+  P3D_VT_list
+} P3D_variant_type;
+
+/* This structure represents a concrete value of some arbitrary type.
+   Instances of this structure may be assigned to property names, or
+   passed into or returned from function calls. */
+typedef struct {
+  P3D_variant_type _type;
 
 
-/* Call this function to query the value of the indicated property.
-   It is an error to call this if the property does not exist; call
-   P3D_instance_has_property() first to ensure this is so.  The return
-   value has been dynamically allocated and should be passed to
-   P3D_free_string() when it is no longer needed. */
-typedef char *
-P3D_instance_get_property_func(P3D_instance *instance,
+  /* Additional opaque data may be stored here. */
+} P3D_variant;
+
+/* Deallocates a P3D_variant previously allocated with one of the
+   below calls, or returned from a function such as
+   P3D_variant_get_property().  After this has been called, the
+   variant's pointer must no longer be used. */
+typedef void
+P3D_variant_finish_func(P3D_variant *variant);
+
+/* Returns a duplicate copy of the indicated variant.  The return
+   value should be eventually passed to P3D_variant_finish(),
+   above. */
+typedef P3D_variant *
+P3D_variant_copy_func(const P3D_variant *variant);
+
+/* Allocates a new P3D_variant of type none.  This variant has no
+   particular value and corresponds to Python's None type or C's void
+   type. */
+typedef P3D_variant *
+P3D_new_none_variant_func();
+
+/* Allocates a new P3D_variant of type bool. */
+typedef P3D_variant *
+P3D_new_bool_variant_func(bool value);
+
+/* Retrieves the boolean value associated with this type.  If the
+   variant's type is not P3D_VT_bool, this implicitly coerces the
+   value to a boolean value. */
+typedef bool
+P3D_variant_get_bool_func(const P3D_variant *variant);
+
+/* Allocates a new P3D_variant of type int. */
+typedef P3D_variant *
+P3D_new_int_variant_func(int value);
+
+/* Retrieves the integer value associated with this type.  If the
+   variant's type is not P3D_VT_int, this implicitly coerces the value
+   to an integer value. */
+typedef int
+P3D_variant_get_int_func(const P3D_variant *variant);
+
+/* Allocates a new P3D_variant of type float. */
+typedef P3D_variant *
+P3D_new_float_variant_func(double value);
+
+/* Retrieves the floating-point value associated with this type.  If
+   the variant's type is not P3D_VT_float, this implicitly coerces the
+   value to a floating-point value. */
+typedef double
+P3D_variant_get_float_func(const P3D_variant *variant);
+
+/* Allocates a new P3D_variant of type string. */
+typedef P3D_variant *
+P3D_new_string_variant_func(const char *value, int length);
+
+/* Retrieves the length of the string value associated with this type.
+   This is the number of bytes that must be allocated to hold the
+   results of P3D_variant_extract_string(), not including any
+   terminating null byte. */
+typedef int
+P3D_variant_get_string_length_func(const P3D_variant *variant);
+
+/* Stores the string value associated with this type in the indicated
+   buffer, which has the specified length.  The return value is the
+   number of characters required for complete representation of the
+   string (which may or may not represent the number of characters
+   actually written).  A terminating null byte is written to the
+   buffer if there is space.  If the variable's type is not
+   P3D_VT_string, this implicitly coerces the value to a string
+   value. */
+typedef int
+P3D_variant_extract_string_func(const P3D_variant *variant, char *buffer, 
+                                int buffer_length);
+
+/* Allocates a new P3D_variant of type list.  This is a list of an
+   arbitrary number of P3D_variant objects.  The indicated P3D_variant
+   objects are stored directly within the list; ownership of the
+   objects in this array (but not the array pointer itself) is passed
+   to the list.  The caller must no longer call P3D_variant_finish()
+   on any objects added to the list (but should still call
+   P3D_variant_finish() on the list itself). */
+typedef P3D_variant *
+P3D_new_list_variant_func(P3D_variant * const elements[], int num_elements);
+
+/* Returns the number of items in the list, if the variant's type is
+   of P3D_VT_list. */
+typedef int
+P3D_variant_get_list_length_func(const P3D_variant *variant);
+
+/* Returns the nth item in the list.  The caller inherits ownership of
+   this object, and should call P3D_variant_finish() on it. */
+typedef P3D_variant *
+P3D_variant_get_list_item_func(const P3D_variant *variant, int n);
+
+/* Retrieves the named property from the instance, if any.  The
+   property name may be a dot-delimited sequence to reference nested
+   properties.  Returns NULL if the instance does not have the named
+   property.  If not NULL, you should pass the return value to
+   P3D_variant_finish(). */
+typedef P3D_variant *
+P3D_instance_get_property_func(const P3D_instance *instance, 
                                const char *property_name);
                                const char *property_name);
 
 
-/* Call this function to set the value of the indicated property. */
-typedef void 
-P3D_instance_set_property_func(P3D_instance *instance,
-                               const char *property_name,
-                               const char *value);
+/* Returns a list of properties on the instance below the named
+   property.  The property name may be a dot-delimited sequence to
+   reference nested properties.  Returns NULL if the instance does not
+   have the named property; otherwise, returns a list variant that
+   contains a list of string variants, one for each property stored on
+   the named property.  If not NULL, you should pass the return value
+   to P3D_variant_finish(). */
+typedef P3D_variant *
+P3D_instance_get_property_list_func(const P3D_instance *instance, 
+                                    const char *property_name);
+
+/* Changes or sets the named property on the instance.  The property
+   name may be a dot-delimited sequence; if so, all of the properties
+   except the last one must already exist.  Returns true on success,
+   false on failure (for instance, because a parent property does not
+   exist).  Pass NULL for the value to delete the last property.  The
+   caller retains ownership of the value object, and should eventually
+   delete with P3D_variant_finish(). */
+typedef bool
+P3D_instance_set_property_func(P3D_instance *instance, const char *property_name,
+                               const P3D_variant *value);
+
+/* Calls the named property as a function.  The property name may be a
+   dot-delimited sequence.  The params variant is an object of type
+   P3D_VT_list, which contains the list of parameters to the function.
+   The caller retains ownership of the params object.  The return
+   value is NULL on error, or a newly-allocated variant on success; if
+   not NULL, you should pass the return value to
+   P3D_variant_finish(). */
+typedef P3D_variant *
+P3D_instance_call_func(P3D_instance *instance, const char *property_name,
+                       const P3D_variant *params);
+
+/* Some scriptable properties on the host may be queried or modified
+   via requests, below. */
 
 
 /********************** REQUEST HANDLING **************************/
 /********************** REQUEST HANDLING **************************/
 
 
@@ -319,10 +448,12 @@ P3D_instance_set_property_func(P3D_instance *instance,
    P3D_instance_get_request.  More types may be added later. */
    P3D_instance_get_request.  More types may be added later. */
 typedef enum {
 typedef enum {
   P3D_RT_stop,
   P3D_RT_stop,
-  P3D_RT_unused, //  P3D_RT_new_config_xml,
   P3D_RT_get_url,
   P3D_RT_get_url,
   P3D_RT_post_url,
   P3D_RT_post_url,
   P3D_RT_notify,
   P3D_RT_notify,
+  P3D_RT_get_property,
+  P3D_RT_set_property,
+  P3D_RT_call,
 } P3D_request_type;
 } P3D_request_type;
 
 
 /* Structures corresponding to the request types in the above enum. */
 /* Structures corresponding to the request types in the above enum. */
@@ -366,6 +497,45 @@ typedef struct {
   const char *_message;
   const char *_message;
 } P3D_request_notify;
 } P3D_request_notify;
 
 
+/* A request to query a property on a host object.  The property_name
+   will be a dot-delimited string corresponding to a nested object.
+   It should begin with "window." for the window object and
+   "document."  for the DOM object that loaded the plugin.  The host
+   should respond to this request by calling P3D_instance_feed_value()
+   with the given unique_id and the requested value, or NULL if the
+   named property does not exist. */
+typedef struct {
+  const char *_property_name;
+  int _unique_id;
+} P3D_request_get_property;
+
+/* A request to change or set a property on a host object.  The
+   property_name will be a dot-delimited string corresponding to a
+   nested object, as above.  _value may be NULL to indicate a request
+   to delete the named property.  The host does *not* receive
+   ownership of the _value pointer and should not store it or delete
+   it.  The host need not respond to this event (other than by calling
+   P3D_request_finish()). */
+typedef struct {
+  const char *_property_name;
+  const P3D_variant *_value;
+} P3D_request_set_property;
+
+/* A request to call a function on a host object.  The property_name
+   will be a dot-delimited string corresponding to a nested object, as
+   above.  The _params pointer will be a list variant, which contains
+   the parameter values to pass to the function.  The host does not
+   receive ownership of the _params pointer and should not store it or
+   delete it.  The host should respond to this request by calling
+   P3D_instance_feed_value() with the given unique_id and the return
+   value of the function, or NULL if the function does not exist or is
+   not a callable object. */
+typedef struct {
+  const char *_property_name;
+  const P3D_variant *_params;
+  int _unique_id;
+} P3D_request_call;
+
 /* This is the overall structure that represents a single request.  It
 /* This is the overall structure that represents a single request.  It
    is returned by P3D_instance_get_request(). */
    is returned by P3D_instance_get_request(). */
 typedef struct {
 typedef struct {
@@ -376,6 +546,9 @@ typedef struct {
     P3D_request_get_url _get_url;
     P3D_request_get_url _get_url;
     P3D_request_post_url _post_url;
     P3D_request_post_url _post_url;
     P3D_request_notify _notify;
     P3D_request_notify _notify;
+    P3D_request_get_property _get_property;
+    P3D_request_set_property _set_property;
+    P3D_request_call _call;
   } _request;
   } _request;
 } P3D_request;
 } P3D_request;
 
 
@@ -477,23 +650,54 @@ P3D_instance_feed_url_stream_func(P3D_instance *instance, int unique_id,
                                   const void *this_data, 
                                   const void *this_data, 
                                   size_t this_data_size);
                                   size_t this_data_size);
 
 
+/* This function is called by the host in response to a get_property
+   or call request.  The instance and unique_id parameters are from
+   the original request; the variant should be a freshly-allocated
+   P3D_variant that represents the requested property value or the
+   return value from the function call, or NULL on error.  Ownership
+   of the variant value is passed into the plugin; the host should
+   *not* call P3D_variant_finish() on this pointer. */
+typedef void
+P3D_instance_feed_value_func(P3D_instance *instance, int unique_id,
+                             P3D_variant *variant);
+
 
 
 #ifdef P3D_FUNCTION_PROTOTYPES
 #ifdef P3D_FUNCTION_PROTOTYPES
 
 
 /* Define all of the actual prototypes for the above functions. */
 /* Define all of the actual prototypes for the above functions. */
 EXPCL_P3D_PLUGIN P3D_initialize_func P3D_initialize;
 EXPCL_P3D_PLUGIN P3D_initialize_func P3D_initialize;
-EXPCL_P3D_PLUGIN P3D_free_string_func P3D_free_string;
+
 EXPCL_P3D_PLUGIN P3D_new_instance_func P3D_new_instance;
 EXPCL_P3D_PLUGIN P3D_new_instance_func P3D_new_instance;
 EXPCL_P3D_PLUGIN P3D_instance_start_func P3D_instance_start;
 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_instance_has_property_func P3D_instance_has_property;
+
+EXPCL_P3D_PLUGIN P3D_variant_finish_func P3D_variant_finish;
+EXPCL_P3D_PLUGIN P3D_variant_copy_func P3D_variant_copy;
+EXPCL_P3D_PLUGIN P3D_new_none_variant_func P3D_new_none_variant;
+EXPCL_P3D_PLUGIN P3D_new_bool_variant_func P3D_new_bool_variant;
+EXPCL_P3D_PLUGIN P3D_variant_get_bool_func P3D_variant_get_bool;
+EXPCL_P3D_PLUGIN P3D_new_int_variant_func P3D_new_int_variant;
+EXPCL_P3D_PLUGIN P3D_variant_get_int_func P3D_variant_get_int;
+EXPCL_P3D_PLUGIN P3D_new_float_variant_func P3D_new_float_variant;
+EXPCL_P3D_PLUGIN P3D_variant_get_float_func P3D_variant_get_float;
+EXPCL_P3D_PLUGIN P3D_new_string_variant_func P3D_new_string_variant;
+EXPCL_P3D_PLUGIN P3D_variant_get_string_length_func P3D_variant_get_string_length;
+EXPCL_P3D_PLUGIN P3D_variant_extract_string_func P3D_variant_extract_string;
+EXPCL_P3D_PLUGIN P3D_new_list_variant_func P3D_new_list_variant;
+EXPCL_P3D_PLUGIN P3D_variant_get_list_length_func P3D_variant_get_list_length;
+EXPCL_P3D_PLUGIN P3D_variant_get_list_item_func P3D_variant_get_list_item;
 EXPCL_P3D_PLUGIN P3D_instance_get_property_func P3D_instance_get_property;
 EXPCL_P3D_PLUGIN P3D_instance_get_property_func P3D_instance_get_property;
+EXPCL_P3D_PLUGIN P3D_instance_get_property_list_func P3D_instance_get_property_list;
 EXPCL_P3D_PLUGIN P3D_instance_set_property_func P3D_instance_set_property;
 EXPCL_P3D_PLUGIN P3D_instance_set_property_func P3D_instance_set_property;
+EXPCL_P3D_PLUGIN P3D_instance_call_func P3D_instance_call;
+
 EXPCL_P3D_PLUGIN P3D_instance_get_request_func P3D_instance_get_request;
 EXPCL_P3D_PLUGIN P3D_instance_get_request_func P3D_instance_get_request;
 EXPCL_P3D_PLUGIN P3D_check_request_func P3D_check_request;
 EXPCL_P3D_PLUGIN P3D_check_request_func P3D_check_request;
 EXPCL_P3D_PLUGIN P3D_request_finish_func P3D_request_finish;
 EXPCL_P3D_PLUGIN P3D_request_finish_func P3D_request_finish;
 EXPCL_P3D_PLUGIN P3D_instance_feed_url_stream_func P3D_instance_feed_url_stream;
 EXPCL_P3D_PLUGIN P3D_instance_feed_url_stream_func P3D_instance_feed_url_stream;
+EXPCL_P3D_PLUGIN P3D_instance_feed_value_func P3D_instance_feed_value;
+
 #endif  /* P3D_FUNCTION_PROTOTYPES */
 #endif  /* P3D_FUNCTION_PROTOTYPES */
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 8 - 0
direct/src/plugin/p3d_plugin_composite1.cxx

@@ -5,8 +5,16 @@
 #include "p3dInstance.cxx"
 #include "p3dInstance.cxx"
 #include "p3dInstanceManager.cxx"
 #include "p3dInstanceManager.cxx"
 #include "p3dMultifileReader.cxx"
 #include "p3dMultifileReader.cxx"
+#include "p3dNoneVariant.cxx"
 #include "p3dPackage.cxx"
 #include "p3dPackage.cxx"
 #include "p3dSplashWindow.cxx"
 #include "p3dSplashWindow.cxx"
 #include "p3dSession.cxx"
 #include "p3dSession.cxx"
 #include "p3dWindowParams.cxx"
 #include "p3dWindowParams.cxx"
 #include "p3dWinSplashWindow.cxx"
 #include "p3dWinSplashWindow.cxx"
+#include "p3dVariant.cxx"
+#include "p3dBoolVariant.cxx"
+#include "p3dIntVariant.cxx"
+#include "p3dFloatVariant.cxx"
+#include "p3dListVariant.cxx"
+#include "p3dStringVariant.cxx"
+