mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
share main object, don't just copy properties
This commit is contained in:
parent
fa35e0c058
commit
d8df46beed
@ -178,7 +178,9 @@ class AppRunner(DirectObject):
|
||||
|
||||
# The "main" object will be exposed to the DOM as a property
|
||||
# of the plugin object; that is, document.pluginobject.main in
|
||||
# JavaScript will be appRunner.main here.
|
||||
# JavaScript will be appRunner.main here. This may be
|
||||
# replaced with a direct reference to the JavaScript object
|
||||
# later, in setInstanceInfo().
|
||||
self.main = ScriptAttributes()
|
||||
|
||||
# By default, we publish a stop() method so the browser can
|
||||
@ -770,7 +772,7 @@ class AppRunner(DirectObject):
|
||||
self.deferredEvals = []
|
||||
|
||||
def setInstanceInfo(self, rootDir, logDirectory, superMirrorUrl,
|
||||
verifyContents):
|
||||
verifyContents, main):
|
||||
""" Called by the browser to set some global information about
|
||||
the instance. """
|
||||
|
||||
@ -792,6 +794,10 @@ class AppRunner(DirectObject):
|
||||
# the latest code?
|
||||
self.verifyContents = verifyContents
|
||||
|
||||
# The initial "main" object, if specified.
|
||||
if main is not None:
|
||||
self.main = main
|
||||
|
||||
# Now that we have rootDir, we can read the config file.
|
||||
self.readConfigXml()
|
||||
|
||||
|
@ -101,9 +101,9 @@ P3DInstance(P3D_request_ready_func *func,
|
||||
int argc, const char *argv[], void *user_data) :
|
||||
_func(func)
|
||||
{
|
||||
_browser_script_object = NULL;
|
||||
_panda_script_object = new P3DMainObject;
|
||||
_panda_script_object->set_instance(this);
|
||||
_dom_object = NULL;
|
||||
_main_object = new P3DMainObject;
|
||||
_main_object->set_instance(this);
|
||||
_user_data = user_data;
|
||||
_request_pending = false;
|
||||
_total_time_reports = 0;
|
||||
@ -180,16 +180,16 @@ P3DInstance(P3D_request_ready_func *func,
|
||||
#endif // __APPLE__
|
||||
|
||||
// Set some initial properties.
|
||||
_panda_script_object->set_float_property("instanceDownloadProgress", 0.0);
|
||||
_panda_script_object->set_float_property("downloadProgress", 0.0);
|
||||
_panda_script_object->set_undefined_property("downloadElapsedSeconds");
|
||||
_panda_script_object->set_undefined_property("downloadElapsedFormatted");
|
||||
_panda_script_object->set_undefined_property("downloadRemainingSeconds");
|
||||
_panda_script_object->set_undefined_property("downloadRemainingFormatted");
|
||||
_panda_script_object->set_string_property("downloadPackageName", "");
|
||||
_panda_script_object->set_string_property("downloadPackageDisplayName", "");
|
||||
_panda_script_object->set_bool_property("downloadComplete", false);
|
||||
_panda_script_object->set_string_property("status", "initial");
|
||||
_main_object->set_float_property("instanceDownloadProgress", 0.0);
|
||||
_main_object->set_float_property("downloadProgress", 0.0);
|
||||
_main_object->set_undefined_property("downloadElapsedSeconds");
|
||||
_main_object->set_undefined_property("downloadElapsedFormatted");
|
||||
_main_object->set_undefined_property("downloadRemainingSeconds");
|
||||
_main_object->set_undefined_property("downloadRemainingFormatted");
|
||||
_main_object->set_string_property("downloadPackageName", "");
|
||||
_main_object->set_string_property("downloadPackageDisplayName", "");
|
||||
_main_object->set_bool_property("downloadComplete", false);
|
||||
_main_object->set_string_property("status", "initial");
|
||||
|
||||
ostringstream stream;
|
||||
stream << inst_mgr->get_plugin_major_version() << "."
|
||||
@ -210,22 +210,22 @@ P3DInstance(P3D_request_ready_func *func,
|
||||
--numeric_version;
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("pluginVersionString", stream.str());
|
||||
_panda_script_object->set_int_property("pluginMajorVersion", inst_mgr->get_plugin_major_version());
|
||||
_panda_script_object->set_int_property("pluginMinorVersion", inst_mgr->get_plugin_minor_version());
|
||||
_panda_script_object->set_int_property("pluginSequenceVersion", inst_mgr->get_plugin_sequence_version());
|
||||
_panda_script_object->set_bool_property("pluginOfficialVersion", inst_mgr->get_plugin_official_version());
|
||||
_panda_script_object->set_int_property("pluginNumericVersion", numeric_version);
|
||||
_panda_script_object->set_string_property("pluginDistributor", inst_mgr->get_plugin_distributor());
|
||||
_panda_script_object->set_string_property("coreapiHostUrl", inst_mgr->get_coreapi_host_url());
|
||||
_main_object->set_string_property("pluginVersionString", stream.str());
|
||||
_main_object->set_int_property("pluginMajorVersion", inst_mgr->get_plugin_major_version());
|
||||
_main_object->set_int_property("pluginMinorVersion", inst_mgr->get_plugin_minor_version());
|
||||
_main_object->set_int_property("pluginSequenceVersion", inst_mgr->get_plugin_sequence_version());
|
||||
_main_object->set_bool_property("pluginOfficialVersion", inst_mgr->get_plugin_official_version());
|
||||
_main_object->set_int_property("pluginNumericVersion", numeric_version);
|
||||
_main_object->set_string_property("pluginDistributor", inst_mgr->get_plugin_distributor());
|
||||
_main_object->set_string_property("coreapiHostUrl", inst_mgr->get_coreapi_host_url());
|
||||
time_t timestamp = inst_mgr->get_coreapi_timestamp();
|
||||
_panda_script_object->set_int_property("coreapiTimestamp", (int)timestamp);
|
||||
_main_object->set_int_property("coreapiTimestamp", (int)timestamp);
|
||||
const char *timestamp_string = ctime(×tamp);
|
||||
if (timestamp_string == NULL) {
|
||||
timestamp_string = "";
|
||||
}
|
||||
_panda_script_object->set_string_property("coreapiTimestampString", timestamp_string);
|
||||
_panda_script_object->set_string_property("coreapiVersionString", inst_mgr->get_coreapi_set_ver());
|
||||
_main_object->set_string_property("coreapiTimestampString", timestamp_string);
|
||||
_main_object->set_string_property("coreapiVersionString", inst_mgr->get_coreapi_set_ver());
|
||||
|
||||
|
||||
// We'll start off with the "download" image displayed in the splash
|
||||
@ -266,17 +266,17 @@ P3DInstance::
|
||||
assert(_session == NULL);
|
||||
cleanup();
|
||||
|
||||
if (_browser_script_object != NULL) {
|
||||
P3D_OBJECT_DECREF(_browser_script_object);
|
||||
_browser_script_object = NULL;
|
||||
if (_dom_object != NULL) {
|
||||
P3D_OBJECT_DECREF(_dom_object);
|
||||
_dom_object = NULL;
|
||||
}
|
||||
|
||||
if (_panda_script_object != NULL) {
|
||||
if (_main_object != NULL) {
|
||||
nout << "panda_script_object ref = "
|
||||
<< _panda_script_object->_ref_count << "\n";
|
||||
_panda_script_object->set_instance(NULL);
|
||||
P3D_OBJECT_DECREF(_panda_script_object);
|
||||
_panda_script_object = NULL;
|
||||
<< _main_object->_ref_count << "\n";
|
||||
_main_object->set_instance(NULL);
|
||||
P3D_OBJECT_DECREF(_main_object);
|
||||
_main_object = NULL;
|
||||
}
|
||||
|
||||
Downloads::iterator di;
|
||||
@ -438,7 +438,7 @@ set_p3d_url(const string &p3d_url) {
|
||||
download->set_total_expected_data(_fparams.lookup_token_int("p3d_size"));
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "downloading_instance");
|
||||
_main_object->set_string_property("status", "downloading_instance");
|
||||
start_download(download);
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@ make_p3d_stream(const string &p3d_url) {
|
||||
download->set_total_expected_data(_fparams.lookup_token_int("p3d_size"));
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "downloading_instance");
|
||||
_main_object->set_string_property("status", "downloading_instance");
|
||||
return start_download(download, false);
|
||||
}
|
||||
|
||||
@ -584,7 +584,7 @@ set_wparams(const P3DWindowParams &wparams) {
|
||||
P3D_object *P3DInstance::
|
||||
get_panda_script_object() const {
|
||||
nout << "get_panda_script_object\n";
|
||||
return _panda_script_object;
|
||||
return _main_object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -599,11 +599,11 @@ get_panda_script_object() const {
|
||||
void P3DInstance::
|
||||
set_browser_script_object(P3D_object *browser_script_object) {
|
||||
nout << "set_browser_script_object\n";
|
||||
if (browser_script_object != _browser_script_object) {
|
||||
P3D_OBJECT_XDECREF(_browser_script_object);
|
||||
_browser_script_object = browser_script_object;
|
||||
if (_browser_script_object != NULL) {
|
||||
P3D_OBJECT_INCREF(_browser_script_object);
|
||||
if (browser_script_object != _dom_object) {
|
||||
P3D_OBJECT_XDECREF(_dom_object);
|
||||
_dom_object = browser_script_object;
|
||||
if (_dom_object != NULL) {
|
||||
P3D_OBJECT_INCREF(_dom_object);
|
||||
}
|
||||
|
||||
if (_session != NULL) {
|
||||
@ -617,8 +617,8 @@ set_browser_script_object(P3D_object *browser_script_object) {
|
||||
_origin_protocol.clear();
|
||||
_origin_hostname.clear();
|
||||
_origin_port.clear();
|
||||
if (_browser_script_object != NULL) {
|
||||
P3D_object *location = P3D_OBJECT_GET_PROPERTY(_browser_script_object, "location");
|
||||
if (_dom_object != NULL) {
|
||||
P3D_object *location = P3D_OBJECT_GET_PROPERTY(_dom_object, "location");
|
||||
if (location != NULL) {
|
||||
P3D_object *protocol = P3D_OBJECT_GET_PROPERTY(location, "protocol");
|
||||
if (protocol != NULL) {
|
||||
@ -717,8 +717,8 @@ get_request() {
|
||||
string message = request->_request._notify._message;
|
||||
string expression = _fparams.lookup_token(message);
|
||||
nout << "notify: " << message << " " << expression << "\n";
|
||||
if (!expression.empty() && _browser_script_object != NULL) {
|
||||
P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str());
|
||||
if (!expression.empty() && _dom_object != NULL) {
|
||||
P3D_object *result = P3D_OBJECT_EVAL(_dom_object, expression.c_str());
|
||||
P3D_OBJECT_XDECREF(result);
|
||||
}
|
||||
}
|
||||
@ -728,14 +728,14 @@ get_request() {
|
||||
{
|
||||
// We also send an implicit message when Python requests itself
|
||||
// to shutdown.
|
||||
_panda_script_object->set_pyobj(NULL);
|
||||
_panda_script_object->set_string_property("status", "stopped");
|
||||
_main_object->set_pyobj(NULL);
|
||||
_main_object->set_string_property("status", "stopped");
|
||||
|
||||
string message = "onpythonstop";
|
||||
string expression = _fparams.lookup_token(message);
|
||||
nout << "notify: " << message << " " << expression << "\n";
|
||||
if (!expression.empty() && _browser_script_object != NULL) {
|
||||
P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str());
|
||||
if (!expression.empty() && _dom_object != NULL) {
|
||||
P3D_object *result = P3D_OBJECT_EVAL(_dom_object, expression.c_str());
|
||||
P3D_OBJECT_XDECREF(result);
|
||||
}
|
||||
}
|
||||
@ -1370,6 +1370,10 @@ make_xml() {
|
||||
xinstance->LinkEndChild(xpackage);
|
||||
}
|
||||
|
||||
TiXmlElement *xmain = _session->p3dobj_to_xml(_main_object);
|
||||
xmain->SetValue("main");
|
||||
xinstance->LinkEndChild(xmain);
|
||||
|
||||
return xinstance;
|
||||
}
|
||||
|
||||
@ -1607,7 +1611,7 @@ priv_set_p3d_filename(const string &p3d_filename, const int &p3d_offset) {
|
||||
}
|
||||
_got_fparams = true;
|
||||
|
||||
_panda_script_object->set_float_property("instanceDownloadProgress", 1.0);
|
||||
_main_object->set_float_property("instanceDownloadProgress", 1.0);
|
||||
|
||||
// Generate a special notification: onpluginload, indicating the
|
||||
// plugin has read its parameters and is ready to be queried (even
|
||||
@ -1938,7 +1942,7 @@ mark_p3d_untrusted() {
|
||||
// button now.
|
||||
|
||||
// Notify JS that we've got no trust of the p3d file.
|
||||
_panda_script_object->set_bool_property("trusted", false);
|
||||
_main_object->set_bool_property("trusted", false);
|
||||
send_notify("onunauth");
|
||||
set_background_image(IT_unauth);
|
||||
set_button_image(IT_auth_ready);
|
||||
@ -1989,7 +1993,7 @@ mark_p3d_trusted() {
|
||||
_session_key = strm.str();
|
||||
|
||||
// Notify JS that we've accepted the trust of the p3d file.
|
||||
_panda_script_object->set_bool_property("trusted", true);
|
||||
_main_object->set_bool_property("trusted", true);
|
||||
send_notify("onauth");
|
||||
|
||||
// Now that we're all set up, start downloading the required
|
||||
@ -2268,8 +2272,8 @@ send_browser_script_object() {
|
||||
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||
xcommand->SetAttribute("cmd", "pyobj");
|
||||
xcommand->SetAttribute("op", "set_browser_script_object");
|
||||
if (_browser_script_object != NULL) {
|
||||
xcommand->LinkEndChild(_session->p3dobj_to_xml(_browser_script_object));
|
||||
if (_dom_object != NULL) {
|
||||
xcommand->LinkEndChild(_session->p3dobj_to_xml(_dom_object));
|
||||
}
|
||||
|
||||
doc->LinkEndChild(xcommand);
|
||||
@ -2418,16 +2422,16 @@ handle_notify_request(const string &message) {
|
||||
if (_matches_script_origin) {
|
||||
// We only actually merge the objects if this web page is
|
||||
// allowed to call our scripting functions.
|
||||
_panda_script_object->set_pyobj(result);
|
||||
_main_object->set_pyobj(result);
|
||||
} else {
|
||||
// Otherwise, we just do a one-time application of the
|
||||
// toplevel properties down to Python.
|
||||
_panda_script_object->apply_properties(result);
|
||||
_main_object->apply_properties(result);
|
||||
}
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "starting");
|
||||
_main_object->set_string_property("status", "starting");
|
||||
|
||||
} else if (message == "onwindowopen") {
|
||||
// The process told us that it just succesfully opened its
|
||||
@ -2444,7 +2448,7 @@ handle_notify_request(const string &message) {
|
||||
}
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "open");
|
||||
_main_object->set_string_property("status", "open");
|
||||
|
||||
} else if (message == "onwindowattach") {
|
||||
// The graphics window has been attached to the browser frame
|
||||
@ -2961,11 +2965,11 @@ ready_to_install() {
|
||||
make_splash_window();
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "downloading");
|
||||
_panda_script_object->set_int_property("numDownloadingPackages", _downloading_packages.size());
|
||||
_panda_script_object->set_int_property("totalDownloadSize", _total_download_size);
|
||||
_panda_script_object->set_int_property("downloadElapsedSeconds", 0);
|
||||
_panda_script_object->set_undefined_property("downloadRemainingSeconds");
|
||||
_main_object->set_string_property("status", "downloading");
|
||||
_main_object->set_int_property("numDownloadingPackages", _downloading_packages.size());
|
||||
_main_object->set_int_property("totalDownloadSize", _total_download_size);
|
||||
_main_object->set_int_property("downloadElapsedSeconds", 0);
|
||||
_main_object->set_undefined_property("downloadRemainingSeconds");
|
||||
|
||||
double progress = 0.0;
|
||||
if (_prev_downloaded != 0) {
|
||||
@ -2974,7 +2978,7 @@ ready_to_install() {
|
||||
progress = (_prev_downloaded) / (_total_download_size + _prev_downloaded);
|
||||
progress = min(progress, 1.0);
|
||||
|
||||
_panda_script_object->set_float_property("downloadProgress", progress);
|
||||
_main_object->set_float_property("downloadProgress", progress);
|
||||
}
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(progress, true, 0);
|
||||
@ -3005,10 +3009,10 @@ start_next_download() {
|
||||
if (!package->get_ready()) {
|
||||
// This package is ready to download. Begin.
|
||||
string name = package->get_formatted_name();
|
||||
_panda_script_object->set_string_property("downloadPackageName", package->get_package_name());
|
||||
_panda_script_object->set_string_property("downloadPackageDisplayName", name);
|
||||
_panda_script_object->set_int_property("downloadPackageNumber", _download_package_index + 1);
|
||||
_panda_script_object->set_int_property("downloadPackageSize", package->get_download_size());
|
||||
_main_object->set_string_property("downloadPackageName", package->get_package_name());
|
||||
_main_object->set_string_property("downloadPackageDisplayName", name);
|
||||
_main_object->set_int_property("downloadPackageNumber", _download_package_index + 1);
|
||||
_main_object->set_int_property("downloadPackageSize", package->get_download_size());
|
||||
set_install_label("Installing " + name);
|
||||
|
||||
nout << "Installing " << package->get_package_name()
|
||||
@ -3049,8 +3053,8 @@ mark_download_complete() {
|
||||
|
||||
if (!_download_complete) {
|
||||
_download_complete = true;
|
||||
_panda_script_object->set_bool_property("downloadComplete", true);
|
||||
_panda_script_object->set_string_property("status", "downloadcomplete");
|
||||
_main_object->set_bool_property("downloadComplete", true);
|
||||
_main_object->set_string_property("status", "downloadcomplete");
|
||||
send_notify("ondownloadcomplete");
|
||||
}
|
||||
|
||||
@ -3079,7 +3083,7 @@ ready_to_start() {
|
||||
return;
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "ready");
|
||||
_main_object->set_string_property("status", "ready");
|
||||
send_notify("onready");
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
@ -3141,7 +3145,7 @@ report_instance_progress(double progress, bool is_progress_known,
|
||||
if (_splash_window != NULL && _show_dl_instance_progress) {
|
||||
_splash_window->set_install_progress(progress, is_progress_known, received_data);
|
||||
}
|
||||
_panda_script_object->set_float_property("instanceDownloadProgress", progress);
|
||||
_main_object->set_float_property("instanceDownloadProgress", progress);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -3178,7 +3182,7 @@ report_package_progress(P3DPackage *package, double progress) {
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(progress, true, 0);
|
||||
}
|
||||
_panda_script_object->set_float_property("downloadProgress", progress);
|
||||
_main_object->set_float_property("downloadProgress", progress);
|
||||
|
||||
static const size_t buffer_size = 256;
|
||||
char buffer[buffer_size];
|
||||
@ -3195,10 +3199,10 @@ report_package_progress(P3DPackage *package, double progress) {
|
||||
#endif
|
||||
|
||||
int ielapsed = (int)elapsed;
|
||||
_panda_script_object->set_int_property("downloadElapsedSeconds", ielapsed);
|
||||
_main_object->set_int_property("downloadElapsedSeconds", ielapsed);
|
||||
|
||||
sprintf(buffer, "%d:%02d", ielapsed / 60, ielapsed % 60);
|
||||
_panda_script_object->set_string_property("downloadElapsedFormatted", buffer);
|
||||
_main_object->set_string_property("downloadElapsedFormatted", buffer);
|
||||
|
||||
if (progress > 0 && (elapsed > 5.0 || progress > 0.2)) {
|
||||
double this_total = elapsed / progress;
|
||||
@ -3227,9 +3231,9 @@ report_package_progress(P3DPackage *package, double progress) {
|
||||
double total = _total_time_reports / (double)_time_reports.size();
|
||||
double remaining = max(total - elapsed, 0.0);
|
||||
int iremaining = (int)(remaining + 0.5);
|
||||
_panda_script_object->set_int_property("downloadRemainingSeconds", iremaining);
|
||||
_main_object->set_int_property("downloadRemainingSeconds", iremaining);
|
||||
sprintf(buffer, "%d:%02d", iremaining / 60, iremaining % 60);
|
||||
_panda_script_object->set_string_property("downloadRemainingFormatted", buffer);
|
||||
_main_object->set_string_property("downloadRemainingFormatted", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,8 +230,8 @@ private:
|
||||
#endif // __APPLE__
|
||||
|
||||
P3D_request_ready_func *_func;
|
||||
P3D_object *_browser_script_object;
|
||||
P3DMainObject *_panda_script_object;
|
||||
P3D_object *_dom_object;
|
||||
P3DMainObject *_main_object;
|
||||
string _p3d_basename;
|
||||
string _origin_protocol;
|
||||
string _origin_hostname;
|
||||
|
@ -281,6 +281,22 @@ output(ostream &out) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DMainObject::
|
||||
set_pyobj(P3D_object *pyobj) {
|
||||
if (pyobj == this) {
|
||||
// We are setting a reference directly to ourselves. This happens
|
||||
// when the application has accepted the main object we gave it in
|
||||
// set_instance_info(). This means the application is directly
|
||||
// manipulating this object as its appRunner.main. In this case,
|
||||
// we don't actually need to set the reference; instead, we clear
|
||||
// anything we had set.
|
||||
nout << "application shares main object\n";
|
||||
pyobj = NULL;
|
||||
|
||||
} else if (pyobj != NULL) {
|
||||
// In the alternate case, the application has its own, separate
|
||||
// appRunner.main object. Thus, we do need to set the pointer.
|
||||
nout << "application has its own main object\n";
|
||||
}
|
||||
|
||||
if (_pyobj != pyobj) {
|
||||
P3D_OBJECT_XDECREF(_pyobj);
|
||||
_pyobj = pyobj;
|
||||
|
@ -1227,9 +1227,20 @@ set_instance_info(P3DCInstance *inst, TiXmlElement *xinstance) {
|
||||
super_mirror = "";
|
||||
}
|
||||
|
||||
// Get the initial "main" object, if specified.
|
||||
PyObject *main;
|
||||
TiXmlElement *xmain = xinstance->FirstChildElement("main");
|
||||
if (xmain != NULL) {
|
||||
main = xml_to_pyobj(xmain);
|
||||
} else {
|
||||
main = Py_None;
|
||||
Py_INCREF(main);
|
||||
}
|
||||
|
||||
PyObject *result = PyObject_CallMethod
|
||||
(_runner, (char *)"setInstanceInfo", (char *)"sssi", root_dir,
|
||||
log_directory, super_mirror, verify_contents);
|
||||
(_runner, (char *)"setInstanceInfo", (char *)"sssiO", root_dir,
|
||||
log_directory, super_mirror, verify_contents, main);
|
||||
Py_DECREF(main);
|
||||
|
||||
if (result == NULL) {
|
||||
PyErr_Print();
|
||||
|
Loading…
x
Reference in New Issue
Block a user