Browse Source

more scripting work

David Rose 16 years ago
parent
commit
e5cb25b7bd

+ 2 - 0
direct/src/plugin_npapi/Sources.pp

@@ -19,11 +19,13 @@
     nppanda3d_common.h \
     ppDownloadRequest.h ppDownloadRequest.I \
     ppInstance.h ppInstance.I \
+    ppObject.h \
     startup.h
 
   #define INCLUDED_SOURCES \
     ppDownloadRequest.cxx \
     ppInstance.cxx \
+    ppObject.cxx \
     startup.cxx
  
   // Windows-specific options.

+ 1 - 0
direct/src/plugin_npapi/nppanda3d_composite1.cxx

@@ -1,5 +1,6 @@
 #include "ppDownloadRequest.cxx"
 #include "ppInstance.cxx"
+#include "ppObject.cxx"
 #include "startup.cxx"
 
 

+ 11 - 0
direct/src/plugin_npapi/ppInstance.I

@@ -12,3 +12,14 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::get_npp_instance
+//       Access: Public
+//  Description: Returns the NPP object corresponding to this
+//               particular instance.
+////////////////////////////////////////////////////////////////////
+inline NPP PPInstance::
+get_npp_instance() const {
+  return _npp_instance;
+}

+ 34 - 0
direct/src/plugin_npapi/ppInstance.cxx

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "ppInstance.h"
+#include "ppObject.h"
 #include "startup.h"
 #include "p3d_plugin_config.h"
 #include "find_root_dir.h"
@@ -37,6 +38,7 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
 
   _npp_instance = instance;
   _npp_mode = mode;
+  _script_object = NULL;
 
   // Copy the tokens and save them within this object.
   _tokens.reserve(argc);
@@ -393,6 +395,30 @@ handle_request(P3D_request *request) {
   P3D_request_finish(request, handled);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::get_script_object
+//       Access: Public
+//  Description: Returns a toplevel object that JavaScript or whatever
+//               can read and/or modify to control the instance.
+////////////////////////////////////////////////////////////////////
+NPObject *PPInstance::
+get_script_object() {
+  logfile << "get_script_object\n" << flush;
+  if (_script_object != NULL) {
+    return _script_object;
+  }
+
+  P3D_object *obj = NULL;
+
+  if (_p3d_inst != NULL) {
+    obj = P3D_instance_get_script_object(_p3d_inst);
+    logfile << "obj = " << obj << "\n" << flush;
+  }
+
+  _script_object = PPObject::make_new(this, obj);
+  logfile << "ppobj = " << _script_object << "\n" << flush;
+  return _script_object;
+}
 
 ////////////////////////////////////////////////////////////////////
 //     Function: PPInstance::read_contents_file
@@ -575,6 +601,14 @@ create_instance() {
     }
     P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size());
     send_window();
+
+    if (_script_object != NULL) {
+      // Now that we have an instance, initialize our script_object
+      // with the proper P3D object pointer.
+      P3D_object *obj = P3D_instance_get_script_object(_p3d_inst);
+      logfile << "late obj = " << obj << "\n" << flush;
+      _script_object->set_p3d_object(obj);
+    }
   }
 }
 

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

@@ -21,6 +21,8 @@
 
 #include <vector>
 
+class PPObject;
+
 ////////////////////////////////////////////////////////////////////
 //       Class : PPInstance
 // Description : This represents a single instance of the Panda3D
@@ -34,6 +36,8 @@ public:
              int16 argc, char *argn[], char *argv[], NPSavedData *saved);
   ~PPInstance();
 
+  inline NPP get_npp_instance() const;
+
   void set_window(NPWindow *window);
   NPError new_stream(NPMIMEType type, NPStream *stream, 
                      bool seekable, uint16 *stype);
@@ -44,6 +48,8 @@ public:
 
   void handle_request(P3D_request *request);
 
+  NPObject *get_script_object();
+
 private:
   bool read_contents_file(const string &filename);
   void get_core_api(TiXmlElement *xpackage);
@@ -72,6 +78,8 @@ private:
   bool _got_window;
   NPWindow _window;
 
+  PPObject *_script_object;
+
   P3D_instance *_p3d_inst;
 };
 

+ 337 - 0
direct/src/plugin_npapi/ppObject.cxx

@@ -0,0 +1,337 @@
+// Filename: ppObject.cxx
+// Created by:  drose (03Jul09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 "ppObject.h"
+
+NPClass PPObject::_object_class = {
+  NP_CLASS_STRUCT_VERSION,
+  &PPObject::NPAllocate,
+  &PPObject::NPDeallocate,
+  &PPObject::NPInvalidate,
+  &PPObject::NPHasMethod,
+  &PPObject::NPInvoke,
+  &PPObject::NPInvokeDefault,
+  &PPObject::NPHasProperty,
+  &PPObject::NPGetProperty,
+  &PPObject::NPSetProperty,
+  &PPObject::NPRemoveProperty,
+#if NP_CLASS_STRUCT_VERSION >= NP_CLASS_STRUCT_VERSION_ENUM
+  &PPObject::NPEnumerate,
+#endif
+#if NP_CLASS_STRUCT_VERSION >= NP_CLASS_STRUCT_VERSION_CTOR
+  &PPObject::NPConstruct,
+#endif
+};
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::make_new
+//       Access: Public, Static
+//  Description: Use this call to construct a new PPObject.
+////////////////////////////////////////////////////////////////////
+PPObject *PPObject::
+make_new(PPInstance *inst, P3D_object *p3d_object) {
+  NPObject *npobj = 
+    browser->createobject(inst->get_npp_instance(), &_object_class);
+  PPObject *ppobj = (PPObject *)npobj;
+  ppobj->construct(p3d_object);
+  return ppobj;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::set_p3d_object
+//       Access: Public
+//  Description: Changes the p3d_object this PPObject maps to.  The
+//               previous object, if any, is deleted.
+////////////////////////////////////////////////////////////////////
+void PPObject::
+set_p3d_object(P3D_object *p3d_object) {
+  if (_p3d_object != p3d_object) {
+    if (_p3d_object != NULL) {
+      P3D_OBJECT_FINISH(_p3d_object);
+    }
+    _p3d_object = p3d_object;
+  }
+}
+ 
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::construct
+//       Access: Private
+//  Description: Stands in for the C++ constructor.  We can't have a
+//               true constructor because of the C-style interface in
+//               NPN_CreateObject().  This must be called explicitly
+//               following NPN_CreateObject().
+////////////////////////////////////////////////////////////////////
+void PPObject::
+construct(P3D_object *p3d_object) {
+  logfile << "construct: " << this << "\n" << flush;
+  _p3d_object = p3d_object;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::invalidate
+//       Access: Private
+//  Description: This "destructor" is called by NPInvalidate().
+////////////////////////////////////////////////////////////////////
+void PPObject::
+invalidate() {
+  logfile << "invalidate: " << this << "\n" << flush;
+  set_p3d_object(NULL);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::has_method
+//       Access: Private
+//  Description: Returns true if the object has the named method,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+has_method(NPIdentifier name) {
+  logfile << "has_method: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::invoke
+//       Access: Private
+//  Description: Calls the named method on the object, storing the
+//               return value into result.  Returns true on success,
+//               false on failure.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount,
+       NPVariant *result) {
+  logfile << "invoke: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::invoke_default
+//       Access: Private
+//  Description: Calls the default method on the object, storing the
+//               return value into result.  Returns true on success,
+//               false on failure.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+invoke_default(const NPVariant *args, uint32_t argCount,
+               NPVariant *result) {
+  logfile << "invoke_default: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::has_property
+//       Access: Private
+//  Description: Returns true if the object has the named property,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+has_property(NPIdentifier name) {
+  logfile << "has_property: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::get_property
+//       Access: Private
+//  Description: Retrieves the named property value from the object
+//               and stores it in result.  Returns true on success,
+//               false on failure.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+get_property(NPIdentifier name, NPVariant *result) {
+  logfile << "get_property: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::set_property
+//       Access: Private
+//  Description: Replaces the named property value on the object.
+//               Returns true on success, false on failure.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+set_property(NPIdentifier name, const NPVariant *value) {
+  logfile << "set_property: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::remove_property
+//       Access: Private
+//  Description: Deletes the named property value from the object.
+//               Returns true on success, false on failure.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+remove_property(NPIdentifier name) {
+  logfile << "remove_property: " << this << "\n" << flush;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::enumerate
+//       Access: Private
+//  Description: Constructs a list of available properties on this
+//               object.  Returns true on success, false on failure.
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+enumerate(NPIdentifier **value, uint32_t *count) {
+  logfile << "enumerate: " << this << "\n" << flush;
+  // TODO: Not implemented yet.
+
+  // Note that the array of values must be allocated here with
+  // NPN_MemAlloc().
+  *value = NULL;
+  *count = 0;
+  return false;
+}
+
+
+// The remaining function bodies are the C-style function wrappers
+// that are called directly by NPAPI, and which redirect into the
+// above C++-style methods.
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPAllocate
+//       Access: Private, Static
+//  Description: Called by NPN_CreateObject() to allocate space for
+//               this object.
+////////////////////////////////////////////////////////////////////
+NPObject *PPObject::
+NPAllocate(NPP npp, NPClass *aClass) {
+  logfile << "NPAllocate\n";
+  assert(aClass == &_object_class);
+  return (PPObject *)malloc(sizeof(PPObject));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::Deallocate
+//       Access: Private, Static
+//  Description: Called to delete the space allocated by NPAllocate,
+//               above.
+////////////////////////////////////////////////////////////////////
+void PPObject::
+NPDeallocate(NPObject *npobj) {
+  logfile << "NPDeallocate: " << npobj << "\n" << flush;
+  free(npobj);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::Deallocate
+//       Access: Private, Static
+//  Description: Called to destruct the object.
+////////////////////////////////////////////////////////////////////
+void PPObject::
+NPInvalidate(NPObject *npobj) {
+  logfile << "NPInvalidate: " << npobj << "\n" << flush;
+  ((PPObject *)npobj)->invalidate();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPHasMethod
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPHasMethod(NPObject *npobj, NPIdentifier name) {
+  return ((PPObject *)npobj)->has_method(name);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPInvoke
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPInvoke(NPObject *npobj, NPIdentifier name,
+         const NPVariant *args, uint32_t argCount,
+         NPVariant *result) {
+  return ((PPObject *)npobj)->invoke(name, args, argCount, result);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPInvokeDefault
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPInvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount,
+                NPVariant *result) {
+  return ((PPObject *)npobj)->invoke_default(args, argCount, result);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPHasProperty
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPHasProperty(NPObject *npobj, NPIdentifier name) {
+  return ((PPObject *)npobj)->has_property(name);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPGetProperty
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) {
+  return ((PPObject *)npobj)->get_property(name, result);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPSetProperty
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) {
+  return ((PPObject *)npobj)->set_property(name, value);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPRemoveProperty
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPRemoveProperty(NPObject *npobj, NPIdentifier name) {
+  return ((PPObject *)npobj)->remove_property(name);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPEnumerate
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) {
+  return ((PPObject *)npobj)->enumerate(value, count);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPObject::NPConstruct
+//       Access: Private, Static
+//  Description: 
+////////////////////////////////////////////////////////////////////
+bool PPObject::
+NPConstruct(NPObject *npobj, const NPVariant *args,
+            uint32_t argCount, NPVariant *result) {
+  // Not implemented.  We don't use this constructor mechanism because
+  // it wasn't supported on earlier versions of Gecko.  Instead, we
+  // use make_new() to construct PPObjects via an explicit call to
+  // construct().
+  return true;
+}

+ 86 - 0
direct/src/plugin_npapi/ppObject.h

@@ -0,0 +1,86 @@
+// Filename: ppObject.h
+// Created by:  drose (03Jul09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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 PPOBJECT_H
+#define PPOBJECT_H
+
+#include "nppanda3d_common.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PPObject
+// Description : This is the interface layer between an NPObject and a
+//               P3D_object.  It maps calls from NPAPI into the
+//               P3D_object system.
+////////////////////////////////////////////////////////////////////
+class PPObject : public NPObject {
+public:
+  static PPObject *make_new(PPInstance *inst, P3D_object *p3d_object);
+
+  inline P3D_object *get_p3d_object() const;
+  void set_p3d_object(P3D_object *p3d_object);
+
+private:
+  void construct(P3D_object *p3d_object);
+  void invalidate();
+
+  bool has_method(NPIdentifier name);
+  bool invoke(NPIdentifier name,
+              const NPVariant *args, uint32_t argCount,
+              NPVariant *result);
+  bool invoke_default(const NPVariant *args, uint32_t argCount,
+                      NPVariant *result);
+  bool has_property(NPIdentifier name);
+  bool get_property(NPIdentifier name,
+                    NPVariant *result);
+  bool set_property(NPIdentifier name,
+                    const NPVariant *value);
+  bool remove_property(NPIdentifier name);
+  bool enumerate(NPIdentifier **value, uint32_t *count);
+
+private:
+  static NPObject *NPAllocate(NPP npp, NPClass *aClass);
+  static void NPDeallocate(NPObject *npobj);
+  static void NPInvalidate(NPObject *npobj);
+  static bool NPHasMethod(NPObject *npobj, NPIdentifier name);
+  static bool NPInvoke(NPObject *npobj, NPIdentifier name,
+                       const NPVariant *args, uint32_t argCount,
+                       NPVariant *result);
+  static bool NPInvokeDefault(NPObject *npobj,
+                              const NPVariant *args,
+                              uint32_t argCount,
+                              NPVariant *result);
+  static bool NPHasProperty(NPObject *npobj, NPIdentifier name);
+  static bool NPGetProperty(NPObject *npobj, NPIdentifier name,
+                            NPVariant *result);
+  static bool NPSetProperty(NPObject *npobj, NPIdentifier name,
+                            const NPVariant *value);
+  static bool NPRemoveProperty(NPObject *npobj,
+                               NPIdentifier name);
+  static bool NPEnumerate(NPObject *npobj, NPIdentifier **value,
+                          uint32_t *count);
+  static bool NPConstruct(NPObject *npobj,
+                          const NPVariant *args,
+                          uint32_t argCount,
+                          NPVariant *result);
+
+private:
+  P3D_object *_p3d_object;
+
+  static NPClass _object_class;
+};
+
+#include "ppObject.I"
+
+#endif
+

+ 7 - 13
direct/src/plugin_npapi/startup.cxx

@@ -396,28 +396,22 @@ NPP_URLNotify(NPP instance, const char *url,
 NPError
 NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
   logfile << "GetValue " << variable << "\n";
+  PPInstance *inst = (PPInstance *)(instance->pdata);
+  assert(inst != NULL);
 
-  /*
   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 *obj = inst->get_script_object();
+    if (obj != NULL) {
+      *(NPObject **)value = obj;
+      return NPERR_NO_ERROR;
     }
-
-    *(NPObject **)value = object;
-    return NPERR_NO_ERROR;
   }
-  */
 
   return NPERR_GENERIC_ERROR;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: NPP_URLNotify
+//     Function: NPP_SetValue
 //  Description: Called by the browser to update a scriptable value.
 ////////////////////////////////////////////////////////////////////
 NPError