Ver código fonte

replace set_property/get_property with evaluate

David Rose 16 anos atrás
pai
commit
3d4b534a68

+ 18 - 41
direct/src/plugin/p3dPythonRun.cxx

@@ -220,16 +220,21 @@ handle_command(TiXmlDocument *doc) {
 
 
       } else if (strcmp(cmd, "feed_value") == 0) {
       } else if (strcmp(cmd, "feed_value") == 0) {
         int instance_id, unique_id;
         int instance_id, unique_id;
-        TiXmlElement *xvalue = xcommand->FirstChildElement("value");
-        if (xvalue != (TiXmlElement *)NULL &&
-            xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS &&
+        if (xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS &&
             xcommand->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
             xcommand->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
           // TODO: deal with instance_id.
           // TODO: deal with instance_id.
-          PyObject *value = from_xml_value(xvalue);
-          PyObject *result = PyObject_CallMethod
-            (_runner, (char*)"feedValue", (char*)"iO", unique_id, value);
-          Py_DECREF(value);
-          Py_XDECREF(result);
+          TiXmlElement *xvalue = xcommand->FirstChildElement("value");
+          if (xvalue != NULL) {
+            PyObject *value = from_xml_value(xvalue);
+            PyObject *result = PyObject_CallMethod
+              (_runner, (char*)"feedValue", (char*)"iOi", unique_id, value, true);
+            Py_DECREF(value);
+            Py_XDECREF(result);
+          } else {
+            PyObject *result = PyObject_CallMethod
+              (_runner, (char*)"feedValue", (char*)"iOi", unique_id, Py_None, false);
+            Py_XDECREF(result);
+          }
         }
         }
         
         
       } else {
       } else {
@@ -319,47 +324,19 @@ py_request_func(PyObject *args) {
     nout << "sending " << doc << "\n" << flush;
     nout << "sending " << doc << "\n" << flush;
     _pipe_write << doc << flush;
     _pipe_write << doc << flush;
 
 
-  } else if (strcmp(request_type, "get_property") == 0) {
-    // A get-property request.
-    const char *property_name;
+  } else if (strcmp(request_type, "evaluate") == 0) {
+    // An evaluate request.
+    const char *expression;
     int unique_id;
     int unique_id;
-    if (!PyArg_ParseTuple(extra_args, "si", &property_name, &unique_id)) {
+    if (!PyArg_ParseTuple(extra_args, "si", &expression, &unique_id)) {
       return NULL;
       return NULL;
     }
     }
 
 
-    xrequest->SetAttribute("property_name", property_name);
+    xrequest->SetAttribute("expression", expression);
     xrequest->SetAttribute("unique_id", unique_id);
     xrequest->SetAttribute("unique_id", unique_id);
     nout << "sending " << doc << "\n" << flush;
     nout << "sending " << doc << "\n" << flush;
     _pipe_write << doc << flush;
     _pipe_write << doc << flush;
 
 
-  } else if (strcmp(request_type, "set_property") == 0) {
-    // A set-property request.
-    const char *property_name;
-    PyObject *value;
-    if (!PyArg_ParseTuple(extra_args, "sO", &property_name, &value)) {
-      return NULL;
-    }
-
-    xrequest->SetAttribute("property_name", property_name);
-    xrequest->LinkEndChild(make_xml_value(value));
-    nout << "sending " << doc << "\n" << flush;
-    _pipe_write << doc << flush;
-
-  } else if (strcmp(request_type, "call") == 0) {
-    // A call-method request.
-    const char *property_name;
-    PyObject *params;
-    int unique_id;
-    if (!PyArg_ParseTuple(extra_args, "sOi", &property_name, &params, &unique_id)) {
-      return NULL;
-    }
-
-    xrequest->SetAttribute("property_name", property_name);
-    xrequest->SetAttribute("unique_id", unique_id);
-    xrequest->LinkEndChild(make_xml_value(params));
-    nout << "sending " << doc << "\n" << flush;
-    _pipe_write << doc << flush;
-
   } else {
   } else {
     string message = string("Unsupported request type: ") + string(request_type);
     string message = string("Unsupported request type: ") + string(request_type);
     PyErr_SetString(PyExc_ValueError, message.c_str());
     PyErr_SetString(PyExc_ValueError, message.c_str());

+ 6 - 29
direct/src/plugin/p3dSession.cxx

@@ -450,37 +450,14 @@ rt_make_p3d_request(TiXmlElement *xrequest) {
         request->_request._notify._message = strdup(message);
         request->_request._notify._message = strdup(message);
       }
       }
 
 
-    } else if (strcmp(rtype, "get_property") == 0) {
-      const char *property_name = xrequest->Attribute("property_name");
+    } else if (strcmp(rtype, "evaluate") == 0) {
+      const char *expression = xrequest->Attribute("expression");
       int unique_id;
       int unique_id;
-      if (property_name != NULL && xrequest->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
+      if (expression != NULL && xrequest->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
         request = new P3D_request;
         request = new P3D_request;
-        request->_request_type = P3D_RT_get_property;
-        request->_request._get_property._property_name = strdup(property_name);
-        request->_request._get_property._unique_id = unique_id;
-      }
-
-    } else if (strcmp(rtype, "set_property") == 0) {
-      const char *property_name = xrequest->Attribute("property_name");
-      TiXmlElement *xvalue = xrequest->FirstChildElement("value");
-      if (property_name != NULL && xvalue != NULL) {
-        request = new P3D_request;
-        request->_request_type = P3D_RT_set_property;
-        request->_request._set_property._property_name = strdup(property_name);
-        request->_request._set_property._value = rt_from_xml_value(xvalue);
-      }
-
-    } else if (strcmp(rtype, "call") == 0) {
-      const char *property_name = xrequest->Attribute("property_name");
-      TiXmlElement *xvalue = xrequest->FirstChildElement("value");
-      int unique_id;
-      if (property_name != NULL && xvalue != NULL && 
-          xrequest->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
-        request = new P3D_request;
-        request->_request_type = P3D_RT_call;
-        request->_request._call._property_name = strdup(property_name);
-        request->_request._call._params = rt_from_xml_value(xvalue);
-        request->_request._call._unique_id = unique_id;
+        request->_request_type = P3D_RT_evaluate;
+        request->_request._evaluate._expression = strdup(expression);
+        request->_request._evaluate._unique_id = unique_id;
       }
       }
 
 
     } else {
     } else {

+ 18 - 49
direct/src/plugin/p3d_plugin.h

@@ -451,9 +451,7 @@ typedef enum {
   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_RT_evaluate,
 } 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. */
@@ -497,44 +495,18 @@ 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. */
+/* A request to evaluate a Javascript expression or statement.  The
+   expression will be evaluated in the context of the parent window.
+   It is particularly useful for querying document state, such as
+   "document.form.username.value", or for changing this state, such as
+   "document.form.choose.red.select = 1".  After evaluating the
+   expression, the host should return the response to this request by
+   calling P3D_instance_feed_value() with the given unique_id and the
+   result value, or NULL if there was an error with the expression. */
 typedef struct {
 typedef struct {
-  const char *_property_name;
+  const char *_expression;
   int _unique_id;
   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_value *_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 value, 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_value *_params;
-  int _unique_id;
-} P3D_request_call;
+} P3D_request_evaluate;
 
 
 /* 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(). */
@@ -546,9 +518,7 @@ 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;
+    P3D_request_evaluate _evaluate;
   } _request;
   } _request;
 } P3D_request;
 } P3D_request;
 
 
@@ -650,13 +620,12 @@ 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 value should be a freshly-allocated
-   P3D_value that represents the requested property value or the
-   return value from the function call, or NULL on error.  Ownership
-   of the value value is passed into the plugin; the host should
-   *not* call P3D_value_finish() on this pointer. */
+/* This function is called by the host in response to an evaulate
+   request.  The instance and unique_id parameters are from the
+   original request; the value should be a freshly-allocated P3D_value
+   that represents the value of the evaluated expression, or NULL on
+   error.  Ownership of the value value is passed into the plugin; the
+   host should *not* call P3D_value_finish() on this pointer. */
 typedef void
 typedef void
 P3D_instance_feed_value_func(P3D_instance *instance, int unique_id,
 P3D_instance_feed_value_func(P3D_instance *instance, int unique_id,
                              P3D_value *value);
                              P3D_value *value);

+ 103 - 1
direct/src/plugin_npapi/ppInstance.cxx

@@ -369,7 +369,17 @@ handle_request(P3D_request *request) {
       browser->geturlnotify(_npp_instance, request->_request._get_url._url,
       browser->geturlnotify(_npp_instance, request->_request._get_url._url,
                             NULL, req);
                             NULL, req);
     }
     }
-    
+    break;
+
+  case P3D_RT_evaluate:
+    {
+      logfile << "Got P3D_RT_evaluate: "
+              << request->_request._evaluate._expression << "\n"
+              << flush;
+      const string &expression = request->_request._evaluate._expression;
+      int unique_id = request->_request._evaluate._unique_id;
+      handle_evaluate(expression, unique_id);
+    }
     break;
     break;
 
 
   default:
   default:
@@ -597,3 +607,95 @@ send_window() {
      0, 0, _window.width, _window.height,
      0, 0, _window.width, _window.height,
      parent_window);
      parent_window);
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::handle_evaluate
+//       Access: Private
+//  Description: Evaluates the script within the window, as requested
+//               by the Panda code.
+////////////////////////////////////////////////////////////////////
+void PPInstance::
+handle_evaluate(const string &expression, int unique_id) {
+  NPObject *window = NULL;
+  if (browser->getvalue(_npp_instance, NPNVWindowNPObject, &window) == NPERR_NO_ERROR) {
+    logfile << "Got object for NPNVWindowNPObject: " << window << "\n";
+    
+    NPString script;
+    script.utf8characters = expression.c_str();
+    script.utf8length = expression.length();
+    NPVariant result;
+    if (browser->evaluate(_npp_instance, window, &script, &result)) {
+      logfile << "Evaluated, result = ";
+      show_np_variant(result);
+      logfile << "\n" << flush;
+
+      P3D_value *value = np_variant_to_value(result);
+      browser->releasevariantvalue(&result);
+
+      P3D_instance_feed_value(_p3d_inst, unique_id, value);
+
+    } else {
+      logfile << "Couldn't evaluate\n";
+    }
+    
+  } else {
+    logfile << "Couldn't get object for NPNVWindowNPObject\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::show_np_variant
+//       Access: Private
+//  Description: Outputs the variant value.
+////////////////////////////////////////////////////////////////////
+void PPInstance::
+show_np_variant(const NPVariant &result) {
+  if (NPVARIANT_IS_NULL(result)) {
+    logfile << "null";
+  } else if (NPVARIANT_IS_VOID(result)) {
+    logfile << "void";
+  } else if (NPVARIANT_IS_BOOLEAN(result)) {
+    logfile << "bool " << NPVARIANT_TO_BOOLEAN(result);
+  } else if (NPVARIANT_IS_INT32(result)) {
+    logfile << "int " << NPVARIANT_TO_INT32(result);
+  } else if (NPVARIANT_IS_DOUBLE(result)) {
+    logfile << "double " << NPVARIANT_TO_DOUBLE(result);
+  } else if (NPVARIANT_IS_STRING(result)) {
+    NPString str = NPVARIANT_TO_STRING(result);
+    logfile << "string " << string(str.utf8characters, str.utf8length);
+  } else if (NPVARIANT_IS_OBJECT(result)) {
+    NPObject *child = NPVARIANT_TO_OBJECT(result);
+    logfile << "object " << child;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::np_variant_to_value
+//       Access: Private
+//  Description: Returns a fresly-allocated P3D_value object
+//               corresponding to the indicated NPVariant.
+////////////////////////////////////////////////////////////////////
+P3D_value *PPInstance::
+np_variant_to_value(const NPVariant &result) {
+  if (NPVARIANT_IS_NULL(result)) {
+    return NULL;
+  } else if (NPVARIANT_IS_VOID(result)) {
+    return P3D_new_none_value();
+  } else if (NPVARIANT_IS_BOOLEAN(result)) {
+    return P3D_new_bool_value(NPVARIANT_TO_BOOLEAN(result));
+  } else if (NPVARIANT_IS_INT32(result)) {
+    return P3D_new_int_value(NPVARIANT_TO_INT32(result));
+  } else if (NPVARIANT_IS_DOUBLE(result)) {
+    return P3D_new_float_value(NPVARIANT_TO_DOUBLE(result));
+  } else if (NPVARIANT_IS_STRING(result)) {
+    NPString str = NPVARIANT_TO_STRING(result);
+    return P3D_new_string_value(str.utf8characters, str.utf8length);
+  } else if (NPVARIANT_IS_OBJECT(result)) {
+    // TODO?
+    return P3D_new_none_value();
+    // NPVARIANT_TO_OBJECT(result);
+  }
+
+  // Huh, what is this?
+  return NULL;
+}

+ 4 - 0
direct/src/plugin_npapi/ppInstance.h

@@ -53,6 +53,10 @@ private:
   void create_instance();
   void create_instance();
   void send_window();
   void send_window();
 
 
+  void handle_evaluate(const string &expression, int unique_id);
+  void show_np_variant(const NPVariant &result);
+  P3D_value *np_variant_to_value(const NPVariant &result);
+
 private:
 private:
   NPP _npp_instance;
   NPP _npp_instance;
   unsigned int _npp_mode;
   unsigned int _npp_mode;

+ 17 - 0
direct/src/plugin_npapi/startup.cxx

@@ -396,6 +396,23 @@ NPP_URLNotify(NPP instance, const char *url,
 NPError
 NPError
 NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
 NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
   logfile << "GetValue " << variable << "\n";
   logfile << "GetValue " << variable << "\n";
+
+  /*
+  if (variable == NPPVpluginScriptableNPObject) {
+    static NPObject *object = NULL;
+    if (object == NULL) {
+      static NPClass npclass;
+      memset(&npclass, 0, sizeof(npclass));
+      npclass.structVersion = NP_CLASS_STRUCT_VERSION;
+      object = browser->createobject(instance, &npclass);
+      assert(object != NULL);
+    }
+
+    *(NPObject **)value = object;
+    return NPERR_NO_ERROR;
+  }
+  */
+
   return NPERR_GENERIC_ERROR;
   return NPERR_GENERIC_ERROR;
 }
 }
 
 

+ 10 - 60
direct/src/plugin_standalone/panda3d.cxx

@@ -406,68 +406,18 @@ handle_request(P3D_request *request) {
     // Ignore notifications.
     // Ignore notifications.
     break;
     break;
 
 
-  case P3D_RT_get_property:
-    cerr << "Got P3D_RT_get_property: "
-         << request->_request._get_property._property_name << "\n";
+  case P3D_RT_evaluate:
+    cerr << "Got P3D_RT_evaluate: "
+         << request->_request._evaluate._expression << "\n";
     {
     {
-      Properties::iterator pi = 
-        _properties.find(request->_request._get_property._property_name);
-      if (pi != _properties.end()) {
-        // The named property has been set.
-        P3D_value *dup_value = P3D_value_copy((*pi).second);
-        P3D_instance_feed_value(request->_instance, 
-                                request->_request._get_property._unique_id,
-                                dup_value);
-      } else {
-        // No such property set.
-        P3D_instance_feed_value(request->_instance, 
-                                request->_request._get_property._unique_id,
-                                NULL);
-      }
-      handled = true;
-    }
-    break;
-
-  case P3D_RT_set_property:
-    cerr << "Got P3D_RT_set_property: "
-         << request->_request._set_property._property_name << "\n";
-    {
-      // Also output the new value.
-      int buffer_size = 
-        P3D_value_get_string_length(request->_request._set_property._value);
-      char *buffer = (char *)alloca(buffer_size);
-      P3D_value_extract_string(request->_request._set_property._value, buffer, buffer_size);
-      cerr.write(buffer, buffer_size);
-      cerr << "\n";
-
-      Properties::iterator pi = 
-        _properties.insert(Properties::value_type(request->_request._set_property._property_name, NULL)).first;
-      if ((*pi).second != NULL) {
-        // Delete the original property.
-        P3D_value_finish((*pi).second);
-      }
-      (*pi).second =
-        P3D_value_copy(request->_request._set_property._value);
-      handled = true;
-    }
-    break;
-
-  case P3D_RT_call:
-    cerr << "Got P3D_RT_call: "
-         << request->_request._call._property_name << "\n";
-    {
-      // Also output the parameter list.
-      int buffer_size = 
-        P3D_value_get_string_length(request->_request._call._params);
-      char *buffer = (char *)alloca(buffer_size);
-      P3D_value_extract_string(request->_request._call._params, buffer, buffer_size);
-      cerr.write(buffer, buffer_size);
-      cerr << "\n";
-
-      // We don't have a mechanism for actually calling anything, though.
+      // In this standalone executable, every expression evaluates to
+      // itself as a string.  We do this just to help debug the
+      // expression passing to and from the low-level Python code.
+      const string &expression = request->_request._evaluate._expression;
+      P3D_value *value = P3D_new_string_value(expression.data(), expression.length());
       P3D_instance_feed_value(request->_instance, 
       P3D_instance_feed_value(request->_instance, 
-                              request->_request._call._unique_id,
-                              NULL);
+                              request->_request._evaluate._unique_id,
+                              value);
       handled = true;
       handled = true;
     }
     }
     break;
     break;

+ 0 - 5
direct/src/plugin_standalone/panda3d.h

@@ -61,11 +61,6 @@ private:
   typedef pset<P3D_instance *> Instances;
   typedef pset<P3D_instance *> Instances;
   Instances _instances;
   Instances _instances;
 
 
-  // We maintain a table of properties in the "browser", mainly so we
-  // can test this feature of the core plugin API.
-  typedef pmap<string, P3D_value *> Properties;
-  Properties _properties;
-
   // This nested class keeps track of active URL requests.
   // This nested class keeps track of active URL requests.
   class URLGetter {
   class URLGetter {
   public:
   public:

+ 4 - 4
direct/src/showutil/runp3d.py

@@ -234,11 +234,11 @@ class AppRunner(DirectObject):
     def sendRequest(self, request, *args):
     def sendRequest(self, request, *args):
         self.requestFunc(self.instanceId, request, args)
         self.requestFunc(self.instanceId, request, args)
 
 
-    def feedValue(self, uniqueId, value):
-        """ Called by the host in response to a 'get_property' or
-        'call' request. """
+    def feedValue(self, uniqueId, value, success):
+        """ Called by the host in response to an 'evaluate'
+        request. """
 
 
-        print "feedValue(%s, %s)" % (uniqueId, value)
+        print "feedValue(%s, %s, %s)" % (uniqueId, value, success)
 
 
     def windowEvent(self, win):
     def windowEvent(self, win):
         print "Got window event in runp3d"
         print "Got window event in runp3d"