support pre-python properties

This commit is contained in:
David Rose 2009-07-10 20:05:14 +00:00
parent e71220779c
commit 19e6ffd5ee
11 changed files with 581 additions and 69 deletions

View File

@ -44,6 +44,7 @@
p3dSession.h p3dSession.I \ p3dSession.h p3dSession.I \
p3dSplashWindow.h p3dSplashWindow.I \ p3dSplashWindow.h p3dSplashWindow.I \
p3dStringObject.h \ p3dStringObject.h \
p3dToplevelObject.h \
p3dUndefinedObject.h \ p3dUndefinedObject.h \
p3dWinSplashWindow.h p3dWinSplashWindow.I \ p3dWinSplashWindow.h p3dWinSplashWindow.I \
p3dX11SplashWindow.h \ p3dX11SplashWindow.h \
@ -69,6 +70,7 @@
p3dSession.cxx \ p3dSession.cxx \
p3dSplashWindow.cxx \ p3dSplashWindow.cxx \
p3dStringObject.cxx \ p3dStringObject.cxx \
p3dToplevelObject.cxx \
p3dUndefinedObject.cxx \ p3dUndefinedObject.cxx \
p3dWinSplashWindow.cxx \ p3dWinSplashWindow.cxx \
p3dX11SplashWindow.cxx \ p3dX11SplashWindow.cxx \

View File

@ -12,8 +12,8 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "p3dFileParams.h" #include "p3dFileParams.h"
#include <ctype.h>
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: P3DFileParams::Default Constructor // Function: P3DFileParams::Default Constructor
@ -37,7 +37,11 @@ P3DFileParams(const string &p3d_filename,
for (size_t i = 0; i < num_tokens; ++i) { for (size_t i = 0; i < num_tokens; ++i) {
Token token; Token token;
if (tokens[i]._keyword != NULL) { if (tokens[i]._keyword != NULL) {
token._keyword = tokens[i]._keyword; // Make the token lowercase, since HTML is case-insensitive but
// we're not.
for (const char *p = tokens[i]._keyword; *p; ++p) {
token._keyword += tolower(*p);
}
} }
if (tokens[i]._value != NULL) { if (tokens[i]._value != NULL) {
token._value = tokens[i]._value; token._value = tokens[i]._value;

View File

@ -21,6 +21,7 @@
#include "p3dWinSplashWindow.h" #include "p3dWinSplashWindow.h"
#include "p3dX11SplashWindow.h" #include "p3dX11SplashWindow.h"
#include "p3dObject.h" #include "p3dObject.h"
#include "p3dToplevelObject.h"
#include "p3dUndefinedObject.h" #include "p3dUndefinedObject.h"
#include <sstream> #include <sstream>
@ -48,6 +49,7 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) :
_func(func) _func(func)
{ {
_browser_script_object = NULL; _browser_script_object = NULL;
_panda_script_object = new P3DToplevelObject;
_user_data = user_data; _user_data = user_data;
_request_pending = false; _request_pending = false;
_got_fparams = false; _got_fparams = false;
@ -62,6 +64,9 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) :
_splash_window = NULL; _splash_window = NULL;
_instance_window_opened = false; _instance_window_opened = false;
_requested_stop = false; _requested_stop = false;
// Set some initial properties.
_panda_script_object->set_float_property("downloadProgress", 0.0);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -71,14 +76,13 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) :
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3DInstance:: P3DInstance::
~P3DInstance() { ~P3DInstance() {
// TODO: maybe this should be a reference-counted object, so we
// don't delete it too soon.
assert(_session == NULL); assert(_session == NULL);
P3D_OBJECT_XDECREF(_browser_script_object); P3D_OBJECT_XDECREF(_browser_script_object);
DESTROY_LOCK(_request_lock); nout << "panda_script_object ref = "
<< _panda_script_object->_ref_count << "\n" << flush;
P3D_OBJECT_DECREF(_panda_script_object);
// Tell all of the packages that we're no longer in business for // Tell all of the packages that we're no longer in business for
// them. // them.
@ -93,6 +97,8 @@ P3DInstance::
_splash_window = NULL; _splash_window = NULL;
} }
DESTROY_LOCK(_request_lock);
// TODO: empty _raw_requests and _baked_requests queues, and // TODO: empty _raw_requests and _baked_requests queues, and
// _downloads map. // _downloads map.
@ -123,6 +129,25 @@ set_fparams(const P3DFileParams &fparams) {
// TODO. // TODO.
_python_version = "python24"; _python_version = "python24";
// Generate a special notification: onpluginload, indicating the
// plugin has read its parameters and is ready to be queried (even
// if Python has not yet started). This notification is special
// because it is the only one generated at this level; the rest of
// them are generated by the Python code, once that is running.
P3D_request *request = new P3D_request;
request->_request_type = P3D_RT_notify;
request->_request._notify._message = strdup("onpluginload");
add_baked_request(request);
// Also eval the HTML associated token.
string expression = _fparams.lookup_token("onpluginload");
if (!expression.empty() && _browser_script_object != NULL) {
P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str());
if (result != NULL) {
nout << "onpluginload returned: " << *result << "\n";
}
P3D_OBJECT_XDECREF(result);
}
// Maybe create the splash window. // Maybe create the splash window.
if (!_instance_window_opened && _got_wparams) { if (!_instance_window_opened && _got_wparams) {
@ -179,35 +204,7 @@ set_wparams(const P3DWindowParams &wparams) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3D_object *P3DInstance:: P3D_object *P3DInstance::
get_panda_script_object() const { get_panda_script_object() const {
assert(_session != NULL); return _panda_script_object;
TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "pyobj");
xcommand->SetAttribute("op", "get_panda_script_object");
doc->LinkEndChild(decl);
doc->LinkEndChild(xcommand);
TiXmlDocument *response = _session->command_and_response(doc);
P3D_object *result = NULL;
if (response != NULL) {
TiXmlElement *xresponse = response->FirstChildElement("response");
if (xresponse != NULL) {
TiXmlElement *xvalue = xresponse->FirstChildElement("value");
if (xvalue != NULL) {
result = _session->xml_to_p3dobj(xvalue);
}
}
delete response;
}
if (result == NULL) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
result = inst_mgr->new_undefined_object();
}
return result;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -557,6 +554,7 @@ make_p3d_request(TiXmlElement *xrequest) {
request = new P3D_request; request = new P3D_request;
request->_request_type = P3D_RT_notify; request->_request_type = P3D_RT_notify;
request->_request._notify._message = strdup(message); request->_request._notify._message = strdup(message);
handle_notify_request(message);
} }
} else if (strcmp(rtype, "script") == 0) { } else if (strcmp(rtype, "script") == 0) {
@ -599,15 +597,6 @@ make_p3d_request(TiXmlElement *xrequest) {
P3D_OBJECT_DECREF(values[i]); P3D_OBJECT_DECREF(values[i]);
} }
} else if (strcmp(rtype, "notify") == 0) {
const char *message = xrequest->Attribute("message");
if (message != NULL) {
request = new P3D_request;
request->_request_type = P3D_RT_notify;
request->_request._notify._message = strdup(message);
handle_notify_request(message);
}
} else if (strcmp(rtype, "drop_p3dobj") == 0) { } else if (strcmp(rtype, "drop_p3dobj") == 0) {
int object_id; int object_id;
if (xrequest->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) { if (xrequest->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {
@ -636,7 +625,39 @@ void P3DInstance::
handle_notify_request(const string &message) { handle_notify_request(const string &message) {
// We look for certain notify events that have particular meaning // We look for certain notify events that have particular meaning
// to this instance. // to this instance.
if (message == "onwindowopen") { nout << "handle_notify: " << message << "\n";
if (message == "onpythonload") {
// Once Python is up and running, we can get the actual toplevel
// object from the Python side, and merge it with our own.
TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "pyobj");
xcommand->SetAttribute("op", "get_panda_script_object");
doc->LinkEndChild(decl);
doc->LinkEndChild(xcommand);
TiXmlDocument *response = _session->command_and_response(doc);
P3D_object *result = NULL;
if (response != NULL) {
TiXmlElement *xresponse = response->FirstChildElement("response");
if (xresponse != NULL) {
TiXmlElement *xvalue = xresponse->FirstChildElement("value");
if (xvalue != NULL) {
result = _session->xml_to_p3dobj(xvalue);
}
}
delete response;
}
if (result != NULL) {
_panda_script_object->set_pyobj(result);
P3D_OBJECT_DECREF(result);
}
} else if (message == "onwindowopen") {
// The process told us that it just succesfully opened its // The process told us that it just succesfully opened its
// window. Tear down the splash window. // window. Tear down the splash window.
_instance_window_opened = true; _instance_window_opened = true;
@ -789,6 +810,7 @@ install_progress(P3DPackage *package, double progress) {
_splash_window->set_install_label("Installing Panda3D"); _splash_window->set_install_label("Installing Panda3D");
_splash_window->set_install_progress(progress); _splash_window->set_install_progress(progress);
} }
_panda_script_object->set_float_property("downloadProgress", progress);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@ class P3DSplashWindow;
class P3DDownload; class P3DDownload;
class P3DPackage; class P3DPackage;
class P3DObject; class P3DObject;
class P3DToplevelObject;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : P3DInstance // Class : P3DInstance
@ -102,6 +103,7 @@ private:
P3D_request_ready_func *_func; P3D_request_ready_func *_func;
P3D_object *_browser_script_object; P3D_object *_browser_script_object;
P3DToplevelObject *_panda_script_object;
bool _got_fparams; bool _got_fparams;
P3DFileParams _fparams; P3DFileParams _fparams;

View File

@ -13,6 +13,10 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "p3dObject.h" #include "p3dObject.h"
#include "p3dBoolObject.h"
#include "p3dIntObject.h"
#include "p3dFloatObject.h"
#include "p3dStringObject.h"
#include <string.h> // strncpy #include <string.h> // strncpy
// The following functions are C-style wrappers around the below // The following functions are C-style wrappers around the below
@ -254,8 +258,8 @@ get_repr(char *buffer, int buffer_length) {
// Function: P3DObject::get_property // Function: P3DObject::get_property
// Access: Public, Virtual // Access: Public, Virtual
// Description: Returns the named property element in the object. The // Description: Returns the named property element in the object. The
// return value is a freshly-allocated P3DObject object // return value is a new-reference P3D_object, or NULL
// that must be deleted by the caller, or NULL on error. // on error.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3D_object *P3DObject:: P3D_object *P3DObject::
get_property(const string &property) { get_property(const string &property) {
@ -323,3 +327,134 @@ output(ostream &out) {
out << value; out << value;
} }
////////////////////////////////////////////////////////////////////
// Function: P3DObject::get_bool_property
// Access: Public
// Description: Returns the value of the named property, as a
// boolean. Returns 0 if the property does not exist.
////////////////////////////////////////////////////////////////////
bool P3DObject::
get_bool_property(const string &property) {
P3D_object *result = get_property(property);
if (result == NULL) {
return 0;
}
bool bresult = P3D_OBJECT_GET_BOOL(result);
P3D_OBJECT_DECREF(result);
return bresult;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::set_bool_property
// Access: Public
// Description: Changes the value of the named property to the
// indicated boolean value.
////////////////////////////////////////////////////////////////////
bool P3DObject::
set_bool_property(const string &property, bool value) {
P3D_object *bvalue = new P3DBoolObject(value);
bool result = set_property(property, bvalue);
P3D_OBJECT_DECREF(bvalue);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::get_int_property
// Access: Public
// Description: Returns the value of the named property, as an
// integer. Returns 0 if the property does not exist.
////////////////////////////////////////////////////////////////////
int P3DObject::
get_int_property(const string &property) {
P3D_object *result = get_property(property);
if (result == NULL) {
return 0;
}
int iresult = P3D_OBJECT_GET_INT(result);
P3D_OBJECT_DECREF(result);
return iresult;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::set_int_property
// Access: Public
// Description: Changes the value of the named property to the
// indicated integer value.
////////////////////////////////////////////////////////////////////
bool P3DObject::
set_int_property(const string &property, int value) {
P3D_object *ivalue = new P3DIntObject(value);
bool result = set_property(property, ivalue);
P3D_OBJECT_DECREF(ivalue);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::get_float_property
// Access: Public
// Description: Returns the value of the named property, as a
// floating-point number. Returns 0.0 if the property
// does not exist.
////////////////////////////////////////////////////////////////////
double P3DObject::
get_float_property(const string &property) {
P3D_object *result = get_property(property);
if (result == NULL) {
return 0.0;
}
double fresult = P3D_OBJECT_GET_FLOAT(result);
P3D_OBJECT_DECREF(result);
return fresult;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::set_float_property
// Access: Public
// Description: Changes the value of the named property to the
// indicated floating-point value.
////////////////////////////////////////////////////////////////////
bool P3DObject::
set_float_property(const string &property, double value) {
P3D_object *fvalue = new P3DFloatObject(value);
bool result = set_property(property, fvalue);
P3D_OBJECT_DECREF(fvalue);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::get_string_property
// Access: Public
// Description: Returns the value of the named property, as a
// string. Returns empty string if the property does
// not exist.
////////////////////////////////////////////////////////////////////
string P3DObject::
get_string_property(const string &property) {
P3D_object *result = get_property(property);
if (result == NULL) {
return string();
}
int size = P3D_OBJECT_GET_STRING(result, NULL, 0);
char *buffer = new char[size];
P3D_OBJECT_GET_STRING(result, buffer, size);
string sresult(buffer, size);
delete[] buffer;
P3D_OBJECT_DECREF(result);
return sresult;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::set_string_property
// Access: Public
// Description: Changes the value of the named property to the
// indicated string value.
////////////////////////////////////////////////////////////////////
bool P3DObject::
set_string_property(const string &property, const string &value) {
P3D_object *svalue = new P3DStringObject(value);
bool result = set_property(property, svalue);
P3D_OBJECT_DECREF(svalue);
return result;
}

View File

@ -52,6 +52,19 @@ public:
virtual void output(ostream &out); virtual void output(ostream &out);
// Convenience functions.
bool get_bool_property(const string &property);
bool set_bool_property(const string &property, bool value);
int get_int_property(const string &property);
bool set_int_property(const string &property, int value);
double get_float_property(const string &property);
bool set_float_property(const string &property, double value);
string get_string_property(const string &property);
bool set_string_property(const string &property, const string &value);
public: public:
static P3D_class_definition _object_class; static P3D_class_definition _object_class;
static P3D_class_definition _generic_class; static P3D_class_definition _generic_class;

View File

@ -134,8 +134,8 @@ make_string(string &value) {
// Function: P3DPythonObject::get_property // Function: P3DPythonObject::get_property
// Access: Public, Virtual // Access: Public, Virtual
// Description: Returns the named property element in the object. The // Description: Returns the named property element in the object. The
// return value is a freshly-allocated P3DPythonObject object // return value is a new-reference P3D_object, or NULL
// that must be deleted by the caller, or NULL on error. // on error.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3D_object *P3DPythonObject:: P3D_object *P3DPythonObject::
get_property(const string &property) { get_property(const string &property) {

View File

@ -0,0 +1,258 @@
// Filename: p3dToplevelObject.cxx
// Created by: drose (10Jul09)
//
////////////////////////////////////////////////////////////////////
//
// 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 "p3dToplevelObject.h"
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
P3DToplevelObject::
P3DToplevelObject() :
_pyobj(NULL)
{
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
P3DToplevelObject::
~P3DToplevelObject() {
set_pyobj(NULL);
// Just in case there are properties we haven't cleared yet.
Properties::const_iterator pi;
for (pi = _properties.begin(); pi != _properties.end(); ++pi) {
P3D_object *value = (*pi).second;
P3D_OBJECT_DECREF(value);
}
_properties.clear();
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_type
// Access: Public, Virtual
// Description: Returns the fundamental type of this kind of object.
////////////////////////////////////////////////////////////////////
P3D_object_type P3DToplevelObject::
get_type() {
return P3D_OT_object;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_bool
// Access: Public, Virtual
// Description: Returns the object value coerced to a boolean, if
// possible.
////////////////////////////////////////////////////////////////////
bool P3DToplevelObject::
get_bool() {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_int
// Access: Public, Virtual
// Description: Returns the object value coerced to an integer, if
// possible.
////////////////////////////////////////////////////////////////////
int P3DToplevelObject::
get_int() {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_float
// Access: Public, Virtual
// Description: Returns the object value coerced to a floating-point
// value, if possible.
////////////////////////////////////////////////////////////////////
double P3DToplevelObject::
get_float() {
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::make_string
// Access: Public, Virtual
// Description: Fills the indicated C++ string object with the value
// of this object coerced to a string.
////////////////////////////////////////////////////////////////////
void P3DToplevelObject::
make_string(string &value) {
if (_pyobj == NULL) {
value = "P3DToplevelObject";
} else {
int size = P3D_OBJECT_GET_STRING(_pyobj, NULL, 0);
char *buffer = new char[size];
P3D_OBJECT_GET_STRING(_pyobj, buffer, size);
value = string(buffer, size);
delete[] buffer;
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_property
// Access: Public, Virtual
// Description: Returns the named property element in the object. The
// return value is a new-reference P3D_object, or NULL
// on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DToplevelObject::
get_property(const string &property) {
if (_pyobj == NULL) {
// Without a pyobj, we just report whatever's been stored locally.
Properties::const_iterator pi;
pi = _properties.find(property);
if (pi != _properties.end()) {
P3D_object *result = (*pi).second;
P3D_OBJECT_INCREF(result);
return result;
}
return NULL;
}
// With a pyobj, we pass the query down to it.
return P3D_OBJECT_GET_PROPERTY(_pyobj, property.c_str());
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::set_property
// Access: Public, Virtual
// Description: Modifies (or deletes, if value is NULL) the named
// property element in the object. Returns true on
// success, false on failure.
////////////////////////////////////////////////////////////////////
bool P3DToplevelObject::
set_property(const string &property, P3D_object *value) {
if (_pyobj == NULL) {
// Without a pyobj, we just store the value locally.
if (value != NULL) {
Properties::iterator pi;
pi = _properties.insert(Properties::value_type(property, NULL)).first;
assert(pi != _properties.end());
P3D_object *orig_value = (*pi).second;
if (orig_value != value) {
P3D_OBJECT_XDECREF(orig_value);
(*pi).second = value;
P3D_OBJECT_INCREF(value);
}
} else {
// Or delete the property locally.
Properties::iterator pi;
pi = _properties.find(property);
if (pi != _properties.end()) {
P3D_object *orig_value = (*pi).second;
P3D_OBJECT_DECREF(orig_value);
_properties.erase(pi);
}
}
return true;
}
// With a pyobj, we pass this request down.
return P3D_OBJECT_SET_PROPERTY(_pyobj, property.c_str(), value);
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::has_method
// Access: Public, Virtual
// Description: Returns true if the named method exists on this
// object, false otherwise.
////////////////////////////////////////////////////////////////////
bool P3DToplevelObject::
has_method(const string &method_name) {
if (_pyobj == NULL) {
// No methods until we get our pyobj.
return false;
}
return P3D_OBJECT_HAS_METHOD(_pyobj, method_name.c_str());
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::call
// Access: Public, Virtual
// Description: Invokes the named method on the object, passing the
// indicated parameters. If the method name is empty,
// invokes the object itself. Returns the return value
// on success, NULL on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DToplevelObject::
call(const string &method_name, P3D_object *params[], int num_params) {
if (_pyobj == NULL) {
// No methods until we get our pyobj.
return NULL;
}
return P3D_OBJECT_CALL(_pyobj, method_name.c_str(), params, num_params);
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::output
// Access: Public, Virtual
// Description: Writes a formatted representation of the value to the
// indicated string. This is intended for developer
// assistance.
////////////////////////////////////////////////////////////////////
void P3DToplevelObject::
output(ostream &out) {
out << "P3DToplevelObject";
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::set_pyobj
// Access: Public
// Description: Changes the internal pyobj pointer. This is the
// P3D_object that references the actual PyObject held
// within the child process, corresponding to the true
// toplevel object there. The new object's reference
// count is incremented, and the previous object's is
// decremented.
////////////////////////////////////////////////////////////////////
void P3DToplevelObject::
set_pyobj(P3D_object *pyobj) {
if (_pyobj != pyobj) {
P3D_OBJECT_XDECREF(_pyobj);
_pyobj = pyobj;
if (_pyobj != NULL) {
P3D_OBJECT_INCREF(_pyobj);
// Now that we have a pyobj, we have to transfer down all of the
// properties we'd set locally.
Properties::const_iterator pi;
for (pi = _properties.begin(); pi != _properties.end(); ++pi) {
const string &property_name = (*pi).first;
P3D_object *value = (*pi).second;
P3D_OBJECT_SET_PROPERTY(_pyobj, property_name.c_str(), value);
P3D_OBJECT_DECREF(value);
}
_properties.clear();
}
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_pyobj
// Access: Public
// Description: Returns the internal pyobj pointer, or NULL if it has
// not yet been set.
////////////////////////////////////////////////////////////////////
P3D_object *P3DToplevelObject::
get_pyobj() const {
return _pyobj;
}

View File

@ -0,0 +1,75 @@
// Filename: p3dToplevelObject.h
// Created by: drose (10Jul09)
//
////////////////////////////////////////////////////////////////////
//
// 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 P3DTOPLEVELOBJECT_H
#define P3DTOPLEVELOBJECT_H
#include "p3d_plugin_common.h"
#include "p3dObject.h"
#include <map>
class P3DSession;
////////////////////////////////////////////////////////////////////
// Class : P3DToplevelObject
// Description : This corresponds to the toplevel "Python" object
// owned by a particular instance, as returned by
// P3DInstance::get_panda_script_object().
//
// This is mostly a wrapper around a P3DPythonObject
// pointer, and therefore functions like any other
// P3DPythonObject; but it also handles the special case
// of being available before Python has been started;
// and it furthermore reports properties that are
// generated directly by the core API (like
// downloadProgress and such).
////////////////////////////////////////////////////////////////////
class P3DToplevelObject : public P3DObject {
public:
P3DToplevelObject();
virtual ~P3DToplevelObject();
public:
virtual P3D_object_type get_type();
virtual bool get_bool();
virtual int get_int();
virtual double get_float();
virtual void make_string(string &value);
virtual P3D_object *get_property(const string &property);
virtual bool set_property(const string &property, P3D_object *value);
virtual bool has_method(const string &method_name);
virtual P3D_object *call(const string &method_name,
P3D_object *params[], int num_params);
virtual void output(ostream &out);
void set_pyobj(P3D_object *pyobj);
P3D_object *get_pyobj() const;
private:
P3D_object *_pyobj;
// This map is used to store properties and retrieve until
// set_pyobj() is called for the firs ttime. At that point, the
// properties stored here are transferred down to the internal
// PyObject.
typedef map<string, P3D_object *> Properties;
Properties _properties;
};
#endif

View File

@ -17,6 +17,7 @@
#include "p3dSession.cxx" #include "p3dSession.cxx"
#include "p3dSplashWindow.cxx" #include "p3dSplashWindow.cxx"
#include "p3dStringObject.cxx" #include "p3dStringObject.cxx"
#include "p3dToplevelObject.cxx"
#include "p3dUndefinedObject.cxx" #include "p3dUndefinedObject.cxx"
#include "p3dWinSplashWindow.cxx" #include "p3dWinSplashWindow.cxx"
#include "p3dX11SplashWindow.cxx" #include "p3dX11SplashWindow.cxx"

View File

@ -423,15 +423,8 @@ handle_request(P3D_request *request) {
break; break;
case P3D_RT_notify: case P3D_RT_notify:
{ // We can ignore notifies, since these are handled by the core
if (_script_object != NULL && // API.
strcmp(request->_request._notify._message, "onpythonload") == 0) {
// Now that Python is running, initialize our script_object
// with the proper P3D object pointer.
P3D_object *obj = P3D_instance_get_panda_script_object(_p3d_inst);
_script_object->set_p3d_object(obj);
}
}
break; break;
default: default:
@ -922,11 +915,6 @@ create_instance() {
return; return;
} }
if (!_got_window) {
// No window yet.
return;
}
_p3d_inst = P3D_new_instance(request_ready, this); _p3d_inst = P3D_new_instance(request_ready, this);
if (_p3d_inst != NULL) { if (_p3d_inst != NULL) {
@ -941,14 +929,26 @@ create_instance() {
logfile << "Couldn't get window_object\n" << flush; logfile << "Couldn't get window_object\n" << flush;
} }
if (_script_object != NULL) {
// Now that we have a true instance, initialize our
// script_object with the proper P3D_object pointer.
P3D_object *obj = P3D_instance_get_panda_script_object(_p3d_inst);
_script_object->set_p3d_object(obj);
}
if (_got_instance_data) {
P3D_token *tokens = NULL; P3D_token *tokens = NULL;
if (!_tokens.empty()) { if (!_tokens.empty()) {
tokens = &_tokens[0]; tokens = &_tokens[0];
} }
P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size()); P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size());
}
if (_got_window) {
send_window(); send_window();
} }
} }
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////