diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 3d06e60191..742e663438 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -17,6 +17,7 @@ p3d_plugin_common.h \ p3dDownload.h p3dDownload.I \ p3dFileDownload.h p3dFileDownload.I \ + p3dFileParams.h p3dFileParams.I \ p3dInstance.h p3dInstance.I \ p3dInstanceManager.h p3dInstanceManager.I \ p3dMultifileReader.h p3dMultifileReader.I \ @@ -30,6 +31,7 @@ p3d_plugin.cxx \ p3dDownload.cxx \ p3dFileDownload.cxx \ + p3dFileParams.cxx \ p3dInstance.cxx \ p3dInstanceManager.cxx \ p3dMultifileReader.cxx \ @@ -67,3 +69,11 @@ p3dPythonRun.cxx p3dPythonRun.h p3dPythonRun.I #end bin_target + +#begin static_lib_target + #define TARGET plugin_common + + #define SOURCES \ + load_plugin.cxx load_plugin.h + +#end static_lib_target diff --git a/direct/src/plugin/load_plugin_src.cxx b/direct/src/plugin/load_plugin.cxx similarity index 73% rename from direct/src/plugin/load_plugin_src.cxx rename to direct/src/plugin/load_plugin.cxx index 96bdf5ade9..8f4f898239 100755 --- a/direct/src/plugin/load_plugin_src.cxx +++ b/direct/src/plugin/load_plugin.cxx @@ -1,4 +1,4 @@ -// Filename: load_plugin_src.cxx +// Filename: load_plugin.cxx // Created by: drose (19Jun09) // //////////////////////////////////////////////////////////////////// @@ -12,11 +12,7 @@ // //////////////////////////////////////////////////////////////////// - -// This code is used in the plugin_standalone directory, and also in -// the plugin_npapi directory. To facilitate that code re-use with -// minimal structural overhead, it is designed to be simply #included -// into the different source files. +#include "load_plugin.h" #ifndef _WIN32 #include @@ -46,42 +42,46 @@ P3D_request_finish_func *P3D_request_finish; P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream; #ifdef _WIN32 -static HMODULE module; +static HMODULE module = NULL; +#else +static void *module = NULL; #endif +static bool plugin_loaded = false; -static void -unload_plugin() { -#ifdef _WIN32 - FreeLibrary(module); - module = NULL; -#else - // TODO: unload_dso -#endif - - P3D_initialize = NULL; - P3D_free_string = NULL; - P3D_create_instance = NULL; - P3D_instance_finish = NULL; - P3D_instance_has_property = NULL; - P3D_instance_get_property = NULL; - P3D_instance_set_property = NULL; - P3D_instance_get_request = NULL; - P3D_check_request = NULL; - P3D_request_finish = NULL; - P3D_instance_feed_url_stream = NULL; +//////////////////////////////////////////////////////////////////// +// Function: get_plugin_basename +// Description: Returns the default plugin filename, without any +// directory path (but including the extension +// appropriate to this platform). +//////////////////////////////////////////////////////////////////// +string +get_plugin_basename() { + return default_plugin_filename + dll_ext; } -static bool +//////////////////////////////////////////////////////////////////// +// Function: load_plugin +// Description: Loads the plugin and assigns all of the function +// pointers. Returns true on success, false on failure. +// If the filename is empty, it is searched along the +// path. +//////////////////////////////////////////////////////////////////// +bool load_plugin(const string &p3d_plugin_filename) { string filename = p3d_plugin_filename; if (filename.empty()) { // Look for the plugin along the path. - filename = default_plugin_filename + dll_ext; + filename = get_plugin_basename(); + } + + if (plugin_loaded) { + return true; } #ifdef _WIN32 + assert(module == NULL); module = LoadLibrary(filename.c_str()); if (module == NULL) { // Couldn't load the DLL. @@ -104,7 +104,8 @@ load_plugin(const string &p3d_plugin_filename) { #else // _WIN32 // Posix case. - void *module = dlopen(filename.c_str(), RTLD_NOW | RTLD_LOCAL); + assert(module == NULL); + module = dlopen(filename.c_str(), RTLD_NOW | RTLD_LOCAL); if (module == NULL) { // Couldn't load the .so. return false; @@ -143,6 +144,8 @@ load_plugin(const string &p3d_plugin_filename) { } // Successfully loaded. + plugin_loaded = true; + #ifdef _WIN32 string logfilename = "c:/cygwin/home/drose/t0.log"; #else @@ -157,3 +160,50 @@ load_plugin(const string &p3d_plugin_filename) { return true; } + +//////////////////////////////////////////////////////////////////// +// Function: unload_plugin +// Description: Removes the plugin from memory space and clears all +// of the pointers. +//////////////////////////////////////////////////////////////////// +void +unload_plugin() { + if (!plugin_loaded) { + return; + } + +#ifdef _WIN32 + assert(module != NULL); + FreeLibrary(module); + module = NULL; +#else + assert(module != NULL); + dlclose(module); + module = NULL; +#endif + + P3D_initialize = NULL; + P3D_free_string = NULL; + P3D_create_instance = NULL; + P3D_instance_finish = NULL; + P3D_instance_has_property = NULL; + P3D_instance_get_property = NULL; + P3D_instance_set_property = NULL; + P3D_instance_get_request = NULL; + P3D_check_request = NULL; + P3D_request_finish = NULL; + P3D_instance_feed_url_stream = NULL; + + plugin_loaded = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: is_plugin_loaded +// Description: Returns true if the plugin has been loaded +// successfully by a previous call to load_plugin(), +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool +is_plugin_loaded() { + return plugin_loaded; +} diff --git a/direct/src/plugin/load_plugin_src.h b/direct/src/plugin/load_plugin.h similarity index 80% rename from direct/src/plugin/load_plugin_src.h rename to direct/src/plugin/load_plugin.h index 8ae6995665..e728464ed4 100755 --- a/direct/src/plugin/load_plugin_src.h +++ b/direct/src/plugin/load_plugin.h @@ -1,4 +1,4 @@ -// Filename: load_plugin_src.h +// Filename: load_plugin.h // Created by: drose (19Jun09) // //////////////////////////////////////////////////////////////////// @@ -12,11 +12,13 @@ // //////////////////////////////////////////////////////////////////// +#ifndef LOAD_PLUGIN_H +#define LOAD_PLUGIN_H -// This code is used in the plugin_standalone directory, and also in -// the plugin_npapi directory. To facilitate that code re-use with -// minimal structural overhead, it is designed to be simply #included -// into the different source files. +#include "p3d_plugin.h" + +#include +using namespace std; extern P3D_initialize_func *P3D_initialize; extern P3D_free_string_func *P3D_free_string; @@ -30,3 +32,10 @@ extern P3D_instance_get_request_func *P3D_instance_get_request; extern P3D_check_request_func *P3D_check_request; extern P3D_request_finish_func *P3D_request_finish; extern P3D_instance_feed_url_stream_func *P3D_instance_feed_url_stream; + +string get_plugin_basename(); +bool load_plugin(const string &p3d_plugin_filename); +void unload_plugin(); +bool is_plugin_loaded(); + +#endif diff --git a/direct/src/plugin/p3dCInstance.I b/direct/src/plugin/p3dCInstance.I index 9b6f08d3ca..4afd8c3ed1 100755 --- a/direct/src/plugin/p3dCInstance.I +++ b/direct/src/plugin/p3dCInstance.I @@ -13,17 +13,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: P3DCInstance::get_p3d_filename -// Access: Public -// Description: Returns the p3d filename that was passed to the -// constructor. -//////////////////////////////////////////////////////////////////// -inline const string &P3DCInstance:: -get_p3d_filename() const { - return _p3d_filename; -} - //////////////////////////////////////////////////////////////////// // Function: P3DCInstance::get_instance_id // Access: Public diff --git a/direct/src/plugin/p3dCInstance.cxx b/direct/src/plugin/p3dCInstance.cxx index 6c0f22c368..9fd9ebbd24 100755 --- a/direct/src/plugin/p3dCInstance.cxx +++ b/direct/src/plugin/p3dCInstance.cxx @@ -25,28 +25,6 @@ P3DCInstance(TiXmlElement *xinstance) : _func(NULL) { xinstance->Attribute("id", &_instance_id); - - const char *p3d_filename = xinstance->Attribute("p3d_filename"); - if (p3d_filename != NULL) { - _p3d_filename = p3d_filename; - } - - TiXmlElement *xtoken = xinstance->FirstChildElement("token"); - while (xtoken != NULL) { - Token token; - const char *keyword = xtoken->Attribute("keyword"); - if (keyword != NULL) { - token._keyword = keyword; - } - - const char *value = xtoken->Attribute("value"); - if (value != NULL) { - token._value = value; - } - - _tokens.push_back(token); - xtoken = xtoken->NextSiblingElement("token"); - } } //////////////////////////////////////////////////////////////////// @@ -57,24 +35,3 @@ P3DCInstance(TiXmlElement *xinstance) : P3DCInstance:: ~P3DCInstance() { } - -//////////////////////////////////////////////////////////////////// -// Function: P3DCInstance::get_py_tokens -// Access: Public -// Description: Returns a Python list object that corresponds to the -// tokens passed to this instance, expressed as a list -// of 2-tuples. New instance. -//////////////////////////////////////////////////////////////////// -PyObject *P3DCInstance:: -get_py_tokens() const { - PyObject *list = PyList_New(_tokens.size()); - - for (size_t i = 0; i < _tokens.size(); ++i) { - const Token &token = _tokens[i]; - PyObject *tuple = Py_BuildValue("(ss)", token._keyword.c_str(), - token._value.c_str()); - PyList_SetItem(list, i, tuple); - } - - return list; -} diff --git a/direct/src/plugin/p3dCInstance.h b/direct/src/plugin/p3dCInstance.h index dd51f1e4f2..976b14007e 100755 --- a/direct/src/plugin/p3dCInstance.h +++ b/direct/src/plugin/p3dCInstance.h @@ -35,23 +35,10 @@ public: P3DCInstance(TiXmlElement *xinstance); ~P3DCInstance(); - inline const string &get_p3d_filename() const; inline int get_instance_id() const; - PyObject *get_py_tokens() const; - private: - class Token { - public: - string _keyword; - string _value; - }; - typedef pvector Tokens; - P3D_request_ready_func *_func; - string _p3d_filename; - - Tokens _tokens; int _instance_id; diff --git a/direct/src/plugin/p3dFileParams.I b/direct/src/plugin/p3dFileParams.I new file mode 100644 index 0000000000..9ef3954c20 --- /dev/null +++ b/direct/src/plugin/p3dFileParams.I @@ -0,0 +1,25 @@ +// Filename: p3dFileParams.I +// Created by: drose (23Jun09) +// +//////////////////////////////////////////////////////////////////// +// +// 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: P3DFileParams::get_p3d_filename +// Access: Public +// Description: Returns the p3d filename that was passed to the +// constructor. +//////////////////////////////////////////////////////////////////// +inline const string &P3DFileParams:: +get_p3d_filename() const { + return _p3d_filename; +} diff --git a/direct/src/plugin/p3dFileParams.cxx b/direct/src/plugin/p3dFileParams.cxx new file mode 100644 index 0000000000..b41e2f39cb --- /dev/null +++ b/direct/src/plugin/p3dFileParams.cxx @@ -0,0 +1,102 @@ +// Filename: p3dFileParams.cxx +// Created by: drose (23Jun09) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "p3dFileParams.h" + +//////////////////////////////////////////////////////////////////// +// Function: P3DFileParams::Default Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DFileParams:: +P3DFileParams() { +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DFileParams::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DFileParams:: +P3DFileParams(const string &p3d_filename, + const P3D_token tokens[], size_t num_tokens) : + _p3d_filename(p3d_filename) +{ + for (size_t i = 0; i < num_tokens; ++i) { + Token token; + if (tokens[i]._keyword != NULL) { + token._keyword = tokens[i]._keyword; + } + if (tokens[i]._value != NULL) { + token._value = tokens[i]._value; + } + _tokens.push_back(token); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DFileParams::Copy Assignment +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void P3DFileParams:: +operator = (const P3DFileParams &other) { + _p3d_filename = other._p3d_filename; + _tokens = other._tokens; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DFileParams::lookup_token +// Access: Public +// Description: Returns the value associated with the first +// appearance of the named token, or empty string if the +// token does not appear. +//////////////////////////////////////////////////////////////////// +string P3DFileParams:: +lookup_token(const string &keyword) const { + Tokens::const_iterator ti; + for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) { + if ((*ti)._keyword == keyword) { + return (*ti)._value; + } + } + + return string(); +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DFileParams::make_xml +// Access: Public +// Description: Returns a newly-allocated XML structure that +// corresponds to the file parameter data within this +// instance. +//////////////////////////////////////////////////////////////////// +TiXmlElement *P3DFileParams:: +make_xml() { + TiXmlElement *xfparams = new TiXmlElement("fparams"); + + xfparams->SetAttribute("p3d_filename", _p3d_filename.c_str()); + + Tokens::const_iterator ti; + for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) { + const Token &token = (*ti); + TiXmlElement *xtoken = new TiXmlElement("token"); + xtoken->SetAttribute("keyword", token._keyword.c_str()); + xtoken->SetAttribute("value", token._value.c_str()); + xfparams->LinkEndChild(xtoken); + } + + return xfparams; +} diff --git a/direct/src/plugin/p3dFileParams.h b/direct/src/plugin/p3dFileParams.h new file mode 100644 index 0000000000..835e077cce --- /dev/null +++ b/direct/src/plugin/p3dFileParams.h @@ -0,0 +1,55 @@ +// Filename: p3dFileParams.h +// Created by: drose (23Jun09) +// +//////////////////////////////////////////////////////////////////// +// +// 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 P3DFILEPARAMS_H +#define P3DFILEPARAMS_H + +#include "p3d_plugin_common.h" + +#include +#include + +//////////////////////////////////////////////////////////////////// +// Class : P3DFileParams +// Description : Encapsulates the file parameters: the p3d_filename, +// and extra tokens. +//////////////////////////////////////////////////////////////////// +class P3DFileParams { +public: + P3DFileParams(); + P3DFileParams(const string &p3d_filename, + const P3D_token tokens[], size_t num_tokens); + + void operator = (const P3DFileParams &other); + + inline const string &get_p3d_filename() const; + string lookup_token(const string &keyword) const; + + TiXmlElement *make_xml(); + +private: + class Token { + public: + string _keyword; + string _value; + }; + typedef vector Tokens; + + string _p3d_filename; + Tokens _tokens; +}; + +#include "p3dFileParams.I" + +#endif diff --git a/direct/src/plugin/p3dInstance.I b/direct/src/plugin/p3dInstance.I index 53314a7523..34633b6725 100644 --- a/direct/src/plugin/p3dInstance.I +++ b/direct/src/plugin/p3dInstance.I @@ -13,6 +13,16 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::get_fparams +// Access: Public +// Description: Returns the current file parameters. +//////////////////////////////////////////////////////////////////// +inline const P3DFileParams &P3DInstance:: +get_fparams() const { + return _fparams; +} + //////////////////////////////////////////////////////////////////// // Function: P3DInstance::get_wparams // Access: Public @@ -23,17 +33,6 @@ get_wparams() const { return _wparams; } -//////////////////////////////////////////////////////////////////// -// Function: P3DInstance::get_p3d_filename -// Access: Public -// Description: Returns the p3d filename that was passed to the -// constructor. -//////////////////////////////////////////////////////////////////// -inline const string &P3DInstance:: -get_p3d_filename() const { - return _p3d_filename; -} - //////////////////////////////////////////////////////////////////// // Function: P3DInstance::get_instance_id // Access: Public diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 4ca22b01ba..5e2fc6b4be 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -31,10 +31,8 @@ P3DInstance(P3D_request_ready_func *func, const string &p3d_filename, const P3D_token tokens[], size_t num_tokens) : _func(func), - _p3d_filename(p3d_filename) + _fparams(p3d_filename, tokens, num_tokens) { - fill_tokens(tokens, num_tokens); - _instance_id = _next_instance_id; ++_next_instance_id; @@ -241,25 +239,6 @@ feed_url_stream(int unique_id, return download_ok; } -//////////////////////////////////////////////////////////////////// -// Function: P3DInstance::lookup_token -// Access: Public -// Description: Returns the value associated with the first -// appearance of the named token, or empty string if the -// token does not appear. -//////////////////////////////////////////////////////////////////// -string P3DInstance:: -lookup_token(const string &keyword) const { - Tokens::const_iterator ti; - for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) { - if ((*ti)._keyword == keyword) { - return (*ti)._value; - } - } - - return string(); -} - //////////////////////////////////////////////////////////////////// // Function: P3DInstance::start_download // Access: Public @@ -321,36 +300,9 @@ TiXmlElement *P3DInstance:: make_xml() { TiXmlElement *xinstance = new TiXmlElement("instance"); xinstance->SetAttribute("id", _instance_id); - xinstance->SetAttribute("p3d_filename", _p3d_filename.c_str()); - Tokens::const_iterator ti; - for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) { - const Token &token = (*ti); - TiXmlElement *xtoken = new TiXmlElement("token"); - xtoken->SetAttribute("keyword", token._keyword.c_str()); - xtoken->SetAttribute("value", token._value.c_str()); - xinstance->LinkEndChild(xtoken); - } + TiXmlElement *xfparams = _fparams.make_xml(); + xinstance->LinkEndChild(xfparams); return xinstance; } - -//////////////////////////////////////////////////////////////////// -// Function: P3DInstance::fill_tokens -// Access: Private -// Description: Copies the C-style tokens array into the internal -// C++-style _tokens vector. -//////////////////////////////////////////////////////////////////// -void P3DInstance:: -fill_tokens(const P3D_token tokens[], size_t num_tokens) { - for (size_t i = 0; i < num_tokens; ++i) { - Token token; - if (tokens[i]._keyword != NULL) { - token._keyword = tokens[i]._keyword; - } - if (tokens[i]._value != NULL) { - token._value = tokens[i]._value; - } - _tokens.push_back(token); - } -} diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index dc61218426..b1c2f8bdeb 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -17,9 +17,9 @@ #include "p3d_plugin_common.h" #include "p3dFileDownload.h" +#include "p3dFileParams.h" #include "p3dWindowParams.h" -#include #include #include #include @@ -39,6 +39,8 @@ public: const P3D_token tokens[], size_t num_tokens); ~P3DInstance(); + inline const P3DFileParams &get_fparams() const; + void set_wparams(const P3DWindowParams &wparams); inline const P3DWindowParams &get_wparams() const; @@ -58,12 +60,9 @@ public: const unsigned char *this_data, size_t this_data_size); - inline const string &get_p3d_filename() const; - inline int get_instance_id() const; inline const string &get_session_key() const; inline const string &get_python_version() const; - string lookup_token(const string &keyword) const; void start_download(P3DDownload *download); void request_stop(); @@ -71,19 +70,9 @@ public: TiXmlElement *make_xml(); private: - void fill_tokens(const P3D_token tokens[], size_t num_tokens); - - class Token { - public: - string _keyword; - string _value; - }; - typedef vector Tokens; - P3D_request_ready_func *_func; - string _p3d_filename; - Tokens _tokens; + P3DFileParams _fparams; P3DWindowParams _wparams; int _instance_id; diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index c79f2441b8..79b667ba1a 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -102,8 +102,8 @@ run_python() { PyErr_Print(); return false; } - _runPackedApp = PyObject_GetAttrString(appmf, "runPackedApp"); - if (_runPackedApp == NULL) { + _setP3DFilename = PyObject_GetAttrString(appmf, "setP3DFilename"); + if (_setP3DFilename == NULL) { PyErr_Print(); return false; } @@ -155,7 +155,7 @@ handle_command(TiXmlDocument *doc) { TiXmlElement *xinstance = xcommand->FirstChildElement("instance"); if (xinstance != (TiXmlElement *)NULL) { P3DCInstance *inst = new P3DCInstance(xinstance); - start_instance(inst); + start_instance(inst, xinstance); } } else if (strcmp(cmd, "terminate_instance") == 0) { int id; @@ -284,20 +284,14 @@ join_read_thread() { // Python process. //////////////////////////////////////////////////////////////////// void P3DPythonRun:: -start_instance(P3DCInstance *inst) { - nout << "starting instance " << inst->get_p3d_filename() << "\n"; +start_instance(P3DCInstance *inst, TiXmlElement *xinstance) { + nout << "starting instance " << inst << "\n"; _instances[inst->get_instance_id()] = inst; - PyObject *tokens = inst->get_py_tokens(); - - PyObject *result = PyObject_CallFunction - (_runPackedApp, "sO", inst->get_p3d_filename().c_str(), tokens); - Py_DECREF(tokens); - - if (result == NULL) { - PyErr_Print(); + TiXmlElement *xfparams = xinstance->FirstChildElement("fparams"); + if (xfparams != (TiXmlElement *)NULL) { + set_p3d_filename(inst, xfparams); } - Py_XDECREF(result); } //////////////////////////////////////////////////////////////////// @@ -323,6 +317,53 @@ terminate_instance(int id) { terminate_session(); } +//////////////////////////////////////////////////////////////////// +// Function: P3DPythonRun::set_p3d_filename +// Access: Private +// Description: Sets the startup filename and tokens for the +// indicated instance. +//////////////////////////////////////////////////////////////////// +void P3DPythonRun:: +set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) { + string p3d_filename; + const char *p3d_filename_c = xfparams->Attribute("p3d_filename"); + if (p3d_filename_c != NULL) { + p3d_filename = p3d_filename_c; + } + + PyObject *token_list = PyList_New(0); + + TiXmlElement *xtoken = xfparams->FirstChildElement("token"); + while (xtoken != NULL) { + string keyword, value; + const char *keyword_c = xtoken->Attribute("keyword"); + if (keyword_c != NULL) { + keyword = keyword_c; + } + + const char *value_c = xtoken->Attribute("value"); + if (value_c != NULL) { + value = value_c; + } + + PyObject *tuple = Py_BuildValue("(ss)", keyword.c_str(), + value.c_str()); + PyList_Append(token_list, tuple); + Py_DECREF(tuple); + + xtoken = xtoken->NextSiblingElement("token"); + } + + PyObject *result = PyObject_CallFunction + (_setP3DFilename, "sO", p3d_filename.c_str(), token_list); + Py_DECREF(token_list); + + if (result == NULL) { + PyErr_Print(); + } + Py_XDECREF(result); +} + //////////////////////////////////////////////////////////////////// // Function: P3DPythonRun::setup_window // Access: Private diff --git a/direct/src/plugin/p3dPythonRun.h b/direct/src/plugin/p3dPythonRun.h index 7a9cbcf446..6fc4e05c05 100755 --- a/direct/src/plugin/p3dPythonRun.h +++ b/direct/src/plugin/p3dPythonRun.h @@ -69,10 +69,11 @@ private: void spawn_read_thread(); void join_read_thread(); - void start_instance(P3DCInstance *inst); + void start_instance(P3DCInstance *inst, TiXmlElement *xinstance); void terminate_instance(int id); + void set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams); void setup_window(int id, TiXmlElement *xwparams); - + void terminate_session(); private: @@ -93,7 +94,7 @@ private: int _py_argc; char **_py_argv; - PyObject *_runPackedApp; + PyObject *_setP3DFilename; PyObject *_setupWindow; PyObject *_taskMgr; diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 44526f8317..c5e0d6d5ca 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -46,7 +46,7 @@ P3DSession(P3DInstance *inst) { _started_read_thread = false; _read_thread_continue = false; - _output_filename = inst->lookup_token("output_filename"); + _output_filename = inst->get_fparams().lookup_token("output_filename"); P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); diff --git a/direct/src/plugin/p3d_plugin_composite1.cxx b/direct/src/plugin/p3d_plugin_composite1.cxx index b14ba336c9..f9fa2dca50 100644 --- a/direct/src/plugin/p3d_plugin_composite1.cxx +++ b/direct/src/plugin/p3d_plugin_composite1.cxx @@ -1,6 +1,7 @@ #include "p3d_plugin.cxx" #include "p3dDownload.cxx" #include "p3dFileDownload.cxx" +#include "p3dFileParams.cxx" #include "p3dInstance.cxx" #include "p3dInstanceManager.cxx" #include "p3dMultifileReader.cxx" diff --git a/direct/src/plugin_npapi/Sources.pp b/direct/src/plugin_npapi/Sources.pp index 714afac87e..f2f2ac5ec1 100644 --- a/direct/src/plugin_npapi/Sources.pp +++ b/direct/src/plugin_npapi/Sources.pp @@ -10,15 +10,19 @@ #define TARGET nppanda3d #define LIB_PREFIX + #define LOCAL_LIBS plugin_common + #define COMBINED_SOURCES \ $[TARGET]_composite1.cxx #define SOURCES \ nppanda3d_common.h \ - nppanda3d_startup.h + ppInstance.h ppInstance.I \ + startup.h #define INCLUDED_SOURCES \ - nppanda3d_startup.cxx + ppInstance.cxx \ + startup.cxx // Windows-specific options. #if $[WINDOWS_PLATFORM] diff --git a/direct/src/plugin_npapi/nppanda3d_common.h b/direct/src/plugin_npapi/nppanda3d_common.h index 58810e6720..4ce39a72d8 100644 --- a/direct/src/plugin_npapi/nppanda3d_common.h +++ b/direct/src/plugin_npapi/nppanda3d_common.h @@ -54,10 +54,11 @@ extern ofstream logfile; #endif // _WIN32, __APPLE__ #include "npapi.h" -//#include "npfunctions.h" #include "npupp.h" -// Appears in nppanda3d_startup.cxx. +#include "load_plugin.h" + +// Appears in startup.cxx. extern NPNetscapeFuncs *browser; #endif diff --git a/direct/src/plugin_npapi/nppanda3d_composite1.cxx b/direct/src/plugin_npapi/nppanda3d_composite1.cxx index e027f1f294..2415b69239 100644 --- a/direct/src/plugin_npapi/nppanda3d_composite1.cxx +++ b/direct/src/plugin_npapi/nppanda3d_composite1.cxx @@ -1,3 +1,4 @@ -#include "nppanda3d_startup.cxx" +#include "ppInstance.cxx" +#include "startup.cxx" diff --git a/direct/src/plugin_npapi/ppInstance.I b/direct/src/plugin_npapi/ppInstance.I new file mode 100644 index 0000000000..acdd7461db --- /dev/null +++ b/direct/src/plugin_npapi/ppInstance.I @@ -0,0 +1,14 @@ +// Filename: ppInstance.I +// Created by: drose (19Jun09) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx new file mode 100644 index 0000000000..4fb7f37cd2 --- /dev/null +++ b/direct/src/plugin_npapi/ppInstance.cxx @@ -0,0 +1,134 @@ +// Filename: ppInstance.cxx +// Created by: drose (19Jun09) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "ppInstance.h" + +//////////////////////////////////////////////////////////////////// +// Function: PPInstance::Constructor +// Access: Public +// Description: Creates a new instance of a Panda3D plugin window. +// The create_data structure is supplied from NPAPI, and +// defines the initial parameters specified in the HTML +// document. +//////////////////////////////////////////////////////////////////// +PPInstance:: +PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode, + int16 argc, char *argn[], char *argv[], NPSavedData *saved) { + logfile << "constructing " << this << "\n" << flush; + _inst = NULL; + + // Copy the tokens and save them within this object. + _tokens.reserve(argc); + for (int i = 0; i < argc; ++i) { + P3D_token token; + token._keyword = strdup(argn[i]); + token._value = strdup(argv[i]); + logfile + << " " << i << ": " << token._keyword << " = " << token._value << "\n"; + _tokens.push_back(token); + } + + _npp_mode = mode; + _got_window = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPInstance::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PPInstance:: +~PPInstance() { + logfile + << "destructing " << this << "\n" << flush; + + if (_inst != NULL) { + P3D_instance_finish(_inst); + _inst = NULL; + } + + // Free the tokens we allocated. + Tokens::iterator ti; + for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) { + free((char *)(*ti)._keyword); + free((char *)(*ti)._value); + } + _tokens.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPInstance::set_window +// Access: Public +// Description: Stores or updates the window parameters. +//////////////////////////////////////////////////////////////////// +void PPInstance:: +set_window(NPWindow *window) { + if (window->x == _window.x && + window->y == _window.y && + window->width == _window.width && + window->height == _window.height) { + // No changes. + return; + } + + _window = *window; + _got_window = true; + + if (_inst != NULL) { + send_window(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PPInstance::create_instance +// Access: Private +// Description: Actually creates the internal P3D_instance object. +//////////////////////////////////////////////////////////////////// +void PPInstance:: +create_instance() { + assert(_inst == NULL); + const P3D_token *tokens = NULL; + if (!_tokens.empty()) { + tokens = &_tokens[0]; + } + + _inst = P3D_create_instance + (NULL, NULL, tokens, _tokens.size()); + + if (_inst != NULL && _got_window) { + send_window(); + } +} + + +//////////////////////////////////////////////////////////////////// +// Function: PPInstance::send_window +// Access: Private +// Description: Actually issues the window parameters to the internal +// P3D_instance object. +//////////////////////////////////////////////////////////////////// +void PPInstance:: +send_window() { + assert(_inst != NULL); + + P3D_window_handle parent_window; +#ifdef _WIN32 + parent_window._hwnd = (HWND)(_window.window); +#endif + + P3D_instance_setup_window + (_inst, P3D_WT_embedded, + _window.x, _window.y, _window.width, _window.height, + parent_window); +} diff --git a/direct/src/plugin_npapi/ppInstance.h b/direct/src/plugin_npapi/ppInstance.h new file mode 100644 index 0000000000..427e4df19a --- /dev/null +++ b/direct/src/plugin_npapi/ppInstance.h @@ -0,0 +1,54 @@ +// Filename: ppInstance.h +// Created by: drose (19Jun09) +// +//////////////////////////////////////////////////////////////////// +// +// 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 PPINSTANCE_H +#define PPINSTANCE_H + +#include "nppanda3d_common.h" + +#include + +//////////////////////////////////////////////////////////////////// +// Class : PPInstance +// Description : This represents a single instance of the Panda3D +// plugin, via the NPAPI interface. This instance +// brokers the communication with the P3D Core API, as +// defined in the plugin directory. +//////////////////////////////////////////////////////////////////// +class PPInstance { +public: + PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode, + int16 argc, char *argn[], char *argv[], NPSavedData *saved); + ~PPInstance(); + + void set_window(NPWindow *window); + +private: + void create_instance(); + void send_window(); + +private: + typedef vector Tokens; + Tokens _tokens; + unsigned int _npp_mode; + + bool _got_window; + NPWindow _window; + + P3D_instance *_inst; +}; + +#include "ppInstance.I" + +#endif diff --git a/direct/src/plugin_npapi/nppanda3d_startup.cxx b/direct/src/plugin_npapi/startup.cxx similarity index 91% rename from direct/src/plugin_npapi/nppanda3d_startup.cxx rename to direct/src/plugin_npapi/startup.cxx index f60646c2a1..941e0b45ca 100644 --- a/direct/src/plugin_npapi/nppanda3d_startup.cxx +++ b/direct/src/plugin_npapi/startup.cxx @@ -1,4 +1,4 @@ -// Filename: nppanda3d_startup.cxx +// Filename: startup.cxx // Created by: drose (17Jun09) // //////////////////////////////////////////////////////////////////// @@ -12,9 +12,7 @@ // //////////////////////////////////////////////////////////////////// -#include "nppanda3d_startup.h" - -#include "../plugin/load_plugin_src.cxx" +#include "startup.h" #ifdef _WIN32 #include @@ -70,7 +68,7 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs, string plugin_location = "/Users/drose/player/direct/built/lib/p3d_plugin.dylib"; #endif - if (!load_plugin(plugin_location.c_str())) { + if (!load_plugin(plugin_location)) { logfile << "couldn't load plugin\n" << flush; return NPERR_INVALID_PLUGIN_ERROR; } @@ -136,16 +134,8 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved) { logfile << "new instance\n" << flush; - // Copy the tokens into a temporary array of P3D_token objects. - P3D_token *tokens = (P3D_token *)alloca(sizeof(P3D_token) * argc); - for (int i = 0; i < argc; ++i) { - P3D_token &token = tokens[i]; - token._keyword = argn[i]; - token._value = argv[i]; - logfile << " " << i << ": " << token._keyword << " = " << token._value << "\n"; - } - - instance->pdata = P3D_create_instance(NULL, NULL, tokens, argc); + instance->pdata = new PPInstance(pluginType, instance, mode, + argc, argn, argv, saved); return NPERR_NO_ERROR; } @@ -159,7 +149,7 @@ NPError NPP_Destroy(NPP instance, NPSavedData **save) { logfile << "destroy instance\n" << flush; (*save) = NULL; - P3D_instance_finish((P3D_instance *)(instance->pdata)); + delete (PPInstance *)(instance->pdata); instance->pdata = NULL; return NPERR_NO_ERROR; @@ -179,20 +169,9 @@ NPP_SetWindow(NPP instance, NPWindow *window) { << ", " << window->width << ", " << window->height << "\n" << flush; - P3D_instance *inst = (P3D_instance *)(instance->pdata); + PPInstance *inst = (PPInstance *)(instance->pdata); assert(inst != NULL); - - P3D_window_handle parent_window; -#ifdef _WIN32 - parent_window._hwnd = (HWND)(window->window); -#endif - - P3D_instance_setup_window - (inst, P3D_WT_embedded, - window->x, window->y, window->width, window->height, - parent_window); - - return NPERR_NO_ERROR; + inst->set_window(window); } //////////////////////////////////////////////////////////////////// @@ -208,8 +187,17 @@ NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype) { logfile << "NewStream " << type << ", " << stream->url << ", " << stream->end << "\n" << flush; + PPInstance *inst = (PPInstance *)(instance->pdata); + assert(inst != NULL); + + //inst->new_stream(type, stream, seekable, stype); + *stype = NP_ASFILEONLY; - return NPERR_NO_ERROR; + + if (strcmp(type, "application/x-panda3d") == 0) { + return NPERR_NO_ERROR; + } + return NPERR_GENERIC_ERROR; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin_npapi/nppanda3d_startup.h b/direct/src/plugin_npapi/startup.h similarity index 86% rename from direct/src/plugin_npapi/nppanda3d_startup.h rename to direct/src/plugin_npapi/startup.h index e93533939d..d212b43b13 100644 --- a/direct/src/plugin_npapi/nppanda3d_startup.h +++ b/direct/src/plugin_npapi/startup.h @@ -1,4 +1,4 @@ -// Filename: nppanda3d_startup.h +// Filename: startup.h // Created by: drose (19Jun09) // //////////////////////////////////////////////////////////////////// @@ -12,13 +12,11 @@ // //////////////////////////////////////////////////////////////////// -#ifndef NPPANDA3D_STARTUP_H -#define NPPANDA3D_STARTUP_H +#ifndef STARTUP_H +#define STARTUP_H #include "nppanda3d_common.h" -#include "../plugin/load_plugin_src.h" - extern "C" { #ifdef _WIN32 NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs); diff --git a/direct/src/plugin_standalone/Sources.pp b/direct/src/plugin_standalone/Sources.pp index c09496f3da..a6d462a1bc 100644 --- a/direct/src/plugin_standalone/Sources.pp +++ b/direct/src/plugin_standalone/Sources.pp @@ -6,6 +6,8 @@ #define USE_PACKAGES openssl zlib #define TARGET panda3d + #define LOCAL_LIBS plugin_common + #define OTHER_LIBS \ prc:c dtoolutil:c dtoolbase:c dtool:m \ interrogatedb:c dconfig:c dtoolconfig:m \ diff --git a/direct/src/plugin_standalone/panda3d.cxx b/direct/src/plugin_standalone/panda3d.cxx index 8b3a79a682..41fa89a007 100644 --- a/direct/src/plugin_standalone/panda3d.cxx +++ b/direct/src/plugin_standalone/panda3d.cxx @@ -34,9 +34,8 @@ #include "thread.h" #include "pset.h" -#include "../plugin/p3d_plugin.h" -#include "../plugin/load_plugin_src.h" -#include "../plugin/load_plugin_src.cxx" +#include "p3d_plugin.h" +#include "load_plugin.h" #ifndef HAVE_GETOPT #include "gnu_getopt.h" @@ -283,7 +282,7 @@ usage() { << "Options:\n\n" - << " -p p3d_plugin" << dll_ext << "\n" + << " -p " << get_plugin_basename() << "\n" << " Specify the full path to the particular Panda plugin DLL to\n" << " run. Normally, this will be found by searching in the usual\n" << " places.\n\n" diff --git a/direct/src/showbase/RunAppMF.py b/direct/src/showbase/RunAppMF.py index 9c180f11ad..c51c70fe91 100644 --- a/direct/src/showbase/RunAppMF.py +++ b/direct/src/showbase/RunAppMF.py @@ -91,17 +91,21 @@ def initPackedAppEnvironment(): # we plan to mount there. vfs.chdir(MultifileRoot) -readyToStart = False +gotWindow = False +gotP3DFilename = False started = False def startIfReady(): - global readyToStart, started - if readyToStart: + global gotWindow, gotP3DFilename, started + if started: + return + + if gotWindow and gotP3DFilename: started = True import main if hasattr(main, 'main') and callable(main.main): main.main() -def runPackedApp(p3dFilename, tokens = []): +def setP3DFilename(p3dFilename, tokens = []): tokenDict = dict(tokens) fname = Filename.fromOsSpecific(p3dFilename) if not p3dFilename: @@ -156,6 +160,8 @@ def runPackedApp(p3dFilename, tokens = []): data = open(pathname, 'r').read() loadPrcFileData(pathname, data) + global gotP3DFilename + gotP3DFilename = True startIfReady() windowPrc = None @@ -185,8 +191,8 @@ def setupWindow(windowType, x, y, width, height, parent): unloadPrcFile(windowPrc) windowPrc = loadPrcFileData("setupWindow", data) - global readyToStart - readyToStart = True + global gotWindow + gotWindow = True startIfReady() def parseSysArgs(): @@ -216,9 +222,9 @@ def parseSysArgs(): if __name__ == '__main__': - readyToStart = True + gotWindow = True try: - runPackedApp(*parseSysArgs()) + setP3DFilename(*parseSysArgs()) except ArgumentError, e: print e.args[0] sys.exit(1)