From e5cb25b7bd0bac64c07fae0c0413f82d2be0ba5d Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 3 Jul 2009 22:41:39 +0000 Subject: [PATCH] more scripting work --- direct/src/plugin_npapi/Sources.pp | 2 + .../src/plugin_npapi/nppanda3d_composite1.cxx | 1 + direct/src/plugin_npapi/ppInstance.I | 11 + direct/src/plugin_npapi/ppInstance.cxx | 34 ++ direct/src/plugin_npapi/ppInstance.h | 8 + direct/src/plugin_npapi/ppObject.cxx | 337 ++++++++++++++++++ direct/src/plugin_npapi/ppObject.h | 86 +++++ direct/src/plugin_npapi/startup.cxx | 20 +- 8 files changed, 486 insertions(+), 13 deletions(-) create mode 100644 direct/src/plugin_npapi/ppObject.cxx create mode 100644 direct/src/plugin_npapi/ppObject.h diff --git a/direct/src/plugin_npapi/Sources.pp b/direct/src/plugin_npapi/Sources.pp index 97cbf55ffb..0b6d16ad3c 100644 --- a/direct/src/plugin_npapi/Sources.pp +++ b/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. diff --git a/direct/src/plugin_npapi/nppanda3d_composite1.cxx b/direct/src/plugin_npapi/nppanda3d_composite1.cxx index b729263d92..d49aa46075 100644 --- a/direct/src/plugin_npapi/nppanda3d_composite1.cxx +++ b/direct/src/plugin_npapi/nppanda3d_composite1.cxx @@ -1,5 +1,6 @@ #include "ppDownloadRequest.cxx" #include "ppInstance.cxx" +#include "ppObject.cxx" #include "startup.cxx" diff --git a/direct/src/plugin_npapi/ppInstance.I b/direct/src/plugin_npapi/ppInstance.I index acdd7461db..8e01119d6a 100644 --- a/direct/src/plugin_npapi/ppInstance.I +++ b/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; +} diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx index 18ac802bc5..bf3f308798 100644 --- a/direct/src/plugin_npapi/ppInstance.cxx +++ b/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); + } } } diff --git a/direct/src/plugin_npapi/ppInstance.h b/direct/src/plugin_npapi/ppInstance.h index 3520f26021..7e20a783ee 100644 --- a/direct/src/plugin_npapi/ppInstance.h +++ b/direct/src/plugin_npapi/ppInstance.h @@ -21,6 +21,8 @@ #include +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; }; diff --git a/direct/src/plugin_npapi/ppObject.cxx b/direct/src/plugin_npapi/ppObject.cxx new file mode 100644 index 0000000000..0820042504 --- /dev/null +++ b/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; +} diff --git a/direct/src/plugin_npapi/ppObject.h b/direct/src/plugin_npapi/ppObject.h new file mode 100644 index 0000000000..cd778b8aa0 --- /dev/null +++ b/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 + diff --git a/direct/src/plugin_npapi/startup.cxx b/direct/src/plugin_npapi/startup.cxx index 1bf575174e..37a150c0a0 100644 --- a/direct/src/plugin_npapi/startup.cxx +++ b/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