mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
support pre-python properties
This commit is contained in:
parent
e71220779c
commit
19e6ffd5ee
@ -44,6 +44,7 @@
|
||||
p3dSession.h p3dSession.I \
|
||||
p3dSplashWindow.h p3dSplashWindow.I \
|
||||
p3dStringObject.h \
|
||||
p3dToplevelObject.h \
|
||||
p3dUndefinedObject.h \
|
||||
p3dWinSplashWindow.h p3dWinSplashWindow.I \
|
||||
p3dX11SplashWindow.h \
|
||||
@ -69,6 +70,7 @@
|
||||
p3dSession.cxx \
|
||||
p3dSplashWindow.cxx \
|
||||
p3dStringObject.cxx \
|
||||
p3dToplevelObject.cxx \
|
||||
p3dUndefinedObject.cxx \
|
||||
p3dWinSplashWindow.cxx \
|
||||
p3dX11SplashWindow.cxx \
|
||||
|
@ -12,8 +12,8 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "p3dFileParams.h"
|
||||
#include <ctype.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DFileParams::Default Constructor
|
||||
@ -37,7 +37,11 @@ P3DFileParams(const string &p3d_filename,
|
||||
for (size_t i = 0; i < num_tokens; ++i) {
|
||||
Token token;
|
||||
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) {
|
||||
token._value = tokens[i]._value;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "p3dWinSplashWindow.h"
|
||||
#include "p3dX11SplashWindow.h"
|
||||
#include "p3dObject.h"
|
||||
#include "p3dToplevelObject.h"
|
||||
#include "p3dUndefinedObject.h"
|
||||
|
||||
#include <sstream>
|
||||
@ -48,6 +49,7 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) :
|
||||
_func(func)
|
||||
{
|
||||
_browser_script_object = NULL;
|
||||
_panda_script_object = new P3DToplevelObject;
|
||||
_user_data = user_data;
|
||||
_request_pending = false;
|
||||
_got_fparams = false;
|
||||
@ -62,6 +64,9 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) :
|
||||
_splash_window = NULL;
|
||||
_instance_window_opened = 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() {
|
||||
// TODO: maybe this should be a reference-counted object, so we
|
||||
// don't delete it too soon.
|
||||
|
||||
assert(_session == NULL);
|
||||
|
||||
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
|
||||
// them.
|
||||
@ -93,6 +97,8 @@ P3DInstance::
|
||||
_splash_window = NULL;
|
||||
}
|
||||
|
||||
DESTROY_LOCK(_request_lock);
|
||||
|
||||
// TODO: empty _raw_requests and _baked_requests queues, and
|
||||
// _downloads map.
|
||||
|
||||
@ -123,6 +129,25 @@ set_fparams(const P3DFileParams &fparams) {
|
||||
// TODO.
|
||||
_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.
|
||||
if (!_instance_window_opened && _got_wparams) {
|
||||
@ -179,35 +204,7 @@ set_wparams(const P3DWindowParams &wparams) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DInstance::
|
||||
get_panda_script_object() const {
|
||||
assert(_session != NULL);
|
||||
|
||||
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;
|
||||
return _panda_script_object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -557,6 +554,7 @@ make_p3d_request(TiXmlElement *xrequest) {
|
||||
request = new P3D_request;
|
||||
request->_request_type = P3D_RT_notify;
|
||||
request->_request._notify._message = strdup(message);
|
||||
handle_notify_request(message);
|
||||
}
|
||||
|
||||
} else if (strcmp(rtype, "script") == 0) {
|
||||
@ -599,15 +597,6 @@ make_p3d_request(TiXmlElement *xrequest) {
|
||||
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) {
|
||||
int object_id;
|
||||
if (xrequest->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {
|
||||
@ -636,7 +625,39 @@ void P3DInstance::
|
||||
handle_notify_request(const string &message) {
|
||||
// We look for certain notify events that have particular meaning
|
||||
// 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
|
||||
// window. Tear down the splash window.
|
||||
_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_progress(progress);
|
||||
}
|
||||
_panda_script_object->set_float_property("downloadProgress", progress);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -30,6 +30,7 @@ class P3DSplashWindow;
|
||||
class P3DDownload;
|
||||
class P3DPackage;
|
||||
class P3DObject;
|
||||
class P3DToplevelObject;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : P3DInstance
|
||||
@ -102,6 +103,7 @@ private:
|
||||
|
||||
P3D_request_ready_func *_func;
|
||||
P3D_object *_browser_script_object;
|
||||
P3DToplevelObject *_panda_script_object;
|
||||
|
||||
bool _got_fparams;
|
||||
P3DFileParams _fparams;
|
||||
|
@ -13,6 +13,10 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "p3dObject.h"
|
||||
#include "p3dBoolObject.h"
|
||||
#include "p3dIntObject.h"
|
||||
#include "p3dFloatObject.h"
|
||||
#include "p3dStringObject.h"
|
||||
#include <string.h> // strncpy
|
||||
|
||||
// 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
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the named property element in the object. The
|
||||
// return value is a freshly-allocated P3DObject object
|
||||
// that must be deleted by the caller, or NULL on error.
|
||||
// return value is a new-reference P3D_object, or NULL
|
||||
// on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DObject::
|
||||
get_property(const string &property) {
|
||||
@ -323,3 +327,134 @@ output(ostream &out) {
|
||||
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;
|
||||
}
|
||||
|
@ -52,6 +52,19 @@ public:
|
||||
|
||||
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:
|
||||
static P3D_class_definition _object_class;
|
||||
static P3D_class_definition _generic_class;
|
||||
|
@ -134,8 +134,8 @@ make_string(string &value) {
|
||||
// Function: P3DPythonObject::get_property
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the named property element in the object. The
|
||||
// return value is a freshly-allocated P3DPythonObject object
|
||||
// that must be deleted by the caller, or NULL on error.
|
||||
// return value is a new-reference P3D_object, or NULL
|
||||
// on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DPythonObject::
|
||||
get_property(const string &property) {
|
||||
|
258
direct/src/plugin/p3dToplevelObject.cxx
Normal file
258
direct/src/plugin/p3dToplevelObject.cxx
Normal 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;
|
||||
}
|
75
direct/src/plugin/p3dToplevelObject.h
Normal file
75
direct/src/plugin/p3dToplevelObject.h
Normal 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
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "p3dSession.cxx"
|
||||
#include "p3dSplashWindow.cxx"
|
||||
#include "p3dStringObject.cxx"
|
||||
#include "p3dToplevelObject.cxx"
|
||||
#include "p3dUndefinedObject.cxx"
|
||||
#include "p3dWinSplashWindow.cxx"
|
||||
#include "p3dX11SplashWindow.cxx"
|
||||
|
@ -423,15 +423,8 @@ handle_request(P3D_request *request) {
|
||||
break;
|
||||
|
||||
case P3D_RT_notify:
|
||||
{
|
||||
if (_script_object != NULL &&
|
||||
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);
|
||||
}
|
||||
}
|
||||
// We can ignore notifies, since these are handled by the core
|
||||
// API.
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -922,11 +915,6 @@ create_instance() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_got_window) {
|
||||
// No window yet.
|
||||
return;
|
||||
}
|
||||
|
||||
_p3d_inst = P3D_new_instance(request_ready, this);
|
||||
|
||||
if (_p3d_inst != NULL) {
|
||||
@ -940,13 +928,25 @@ create_instance() {
|
||||
} else {
|
||||
logfile << "Couldn't get window_object\n" << flush;
|
||||
}
|
||||
|
||||
P3D_token *tokens = NULL;
|
||||
if (!_tokens.empty()) {
|
||||
tokens = &_tokens[0];
|
||||
|
||||
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;
|
||||
if (!_tokens.empty()) {
|
||||
tokens = &_tokens[0];
|
||||
}
|
||||
P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size());
|
||||
}
|
||||
|
||||
if (_got_window) {
|
||||
send_window();
|
||||
}
|
||||
P3D_instance_start(_p3d_inst, _p3d_filename.c_str(), tokens, _tokens.size());
|
||||
send_window();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user