'main' object

This commit is contained in:
David Rose 2009-08-21 22:42:35 +00:00
parent d16605943f
commit f34abe4411
17 changed files with 487 additions and 82 deletions

View File

@ -36,6 +36,7 @@
p3dInstance.h p3dInstance.I \
p3dInstanceManager.h p3dInstanceManager.I \
p3dIntObject.h \
p3dMainObject.h \
p3dMultifileReader.h p3dMultifileReader.I \
p3dNoneObject.h \
p3dObject.h p3dObject.I \
@ -47,7 +48,6 @@
p3dSplashWindow.h p3dSplashWindow.I \
p3dStringObject.h \
p3dTemporaryFile.h p3dTemporaryFile.I \
p3dToplevelObject.h \
p3dUndefinedObject.h \
p3dWinSplashWindow.h p3dWinSplashWindow.I \
p3dX11SplashWindow.h \
@ -67,6 +67,7 @@
p3dInstance.cxx \
p3dInstanceManager.cxx \
p3dIntObject.cxx \
p3dMainObject.cxx \
p3dMultifileReader.cxx \
p3dNoneObject.cxx \
p3dObject.cxx \
@ -78,7 +79,6 @@
p3dSplashWindow.cxx \
p3dStringObject.cxx \
p3dTemporaryFile.cxx \
p3dToplevelObject.cxx \
p3dUndefinedObject.cxx \
p3dWinSplashWindow.cxx \
p3dX11SplashWindow.cxx \

View File

@ -94,33 +94,33 @@ quick_verify(const string &package_dir) const {
string pathname = get_pathname(package_dir);
struct stat st;
if (stat(pathname.c_str(), &st) != 0) {
//nout << "file not found: " << _filename << "\n";
//cerr << "file not found: " << _filename << "\n";
return false;
}
if (st.st_size != _size) {
// If the size is wrong, the file fails.
//nout << "size wrong: " << _filename << "\n";
//cerr << "size wrong: " << _filename << "\n";
return false;
}
if (st.st_mtime == _timestamp) {
// If the size is right and the timestamp is right, the file passes.
//nout << "file ok: " << _filename << "\n";
//cerr << "file ok: " << _filename << "\n";
return true;
}
//nout << "modification time wrong: " << _filename << "\n";
//cerr << "modification time wrong: " << _filename << "\n";
// If the size is right but the timestamp is wrong, the file
// soft-fails. We follow this up with a hash check.
if (!check_hash(pathname)) {
// Hard fail, the hash is wrong.
//nout << "hash check wrong: " << _filename << "\n";
//cerr << "hash check wrong: " << _filename << "\n";
return false;
}
//nout << "hash check ok: " << _filename << "\n";
//cerr << "hash check ok: " << _filename << "\n";
// The hash is OK after all. Change the file's timestamp back to
// what we expect it to be, so we can quick-verify it successfully
@ -149,13 +149,13 @@ full_verify(const string &package_dir) const {
string pathname = get_pathname(package_dir);
struct stat st;
if (stat(pathname.c_str(), &st) != 0) {
//nout << "file not found: " << _filename << "\n";
//cerr << "file not found: " << _filename << "\n";
return false;
}
if (st.st_size != _size) {
// If the size is wrong, the file fails.
//nout << "size wrong: " << _filename << "\n";
//cerr << "size wrong: " << _filename << "\n";
return false;
}
@ -163,11 +163,11 @@ full_verify(const string &package_dir) const {
// soft-fails. We follow this up with a hash check.
if (!check_hash(pathname)) {
// Hard fail, the hash is wrong.
//nout << "hash check wrong: " << _filename << "\n";
//cerr << "hash check wrong: " << _filename << "\n";
return false;
}
//nout << "hash check ok: " << _filename << "\n";
//cerr << "hash check ok: " << _filename << "\n";
// The hash is OK. If the timestamp is wrong, change it back to
// what we expect it to be, so we can quick-verify it successfully
@ -193,7 +193,7 @@ bool FileSpec::
check_hash(const string &pathname) const {
ifstream stream(pathname.c_str(), ios::in | ios::binary);
if (!stream) {
//nout << "unable to read " << pathname << "\n";
//cerr << "unable to read " << pathname << "\n";
return false;
}

View File

@ -22,7 +22,7 @@
#include "p3dOsxSplashWindow.h"
#include "p3dX11SplashWindow.h"
#include "p3dObject.h"
#include "p3dToplevelObject.h"
#include "p3dMainObject.h"
#include "p3dUndefinedObject.h"
#include "p3dMultifileReader.h"
#include "p3dTemporaryFile.h"
@ -57,7 +57,7 @@ P3DInstance(P3D_request_ready_func *func,
_func(func)
{
_browser_script_object = NULL;
_panda_script_object = new P3DToplevelObject;
_panda_script_object = new P3DMainObject;
_user_data = user_data;
_request_pending = false;
_temp_p3d_filename = NULL;
@ -1011,7 +1011,7 @@ handle_notify_request(const string &message) {
// to this instance.
nout << "Got notify: " << message << "\n";
if (message == "onpythonload") {
// Once Python is up and running, we can get the actual toplevel
// Once Python is up and running, we can get the actual main
// object from the Python side, and merge it with our own.
TiXmlDocument *doc = new TiXmlDocument;

View File

@ -39,7 +39,7 @@ class P3DSplashWindow;
class P3DDownload;
class P3DPackage;
class P3DObject;
class P3DToplevelObject;
class P3DMainObject;
class P3DTemporaryFile;
////////////////////////////////////////////////////////////////////
@ -144,7 +144,7 @@ private:
P3D_request_ready_func *_func;
P3D_object *_browser_script_object;
P3DToplevelObject *_panda_script_object;
P3DMainObject *_panda_script_object;
P3DTemporaryFile *_temp_p3d_filename;
P3DTemporaryFile *_temp_splash_image;

View File

@ -49,7 +49,7 @@ P3DInstanceManager *P3DInstanceManager::_global_ptr;
P3DInstanceManager::
P3DInstanceManager() {
_is_initialized = false;
_next_temp_filename_counter = 0;
_next_temp_filename_counter = 1;
_unique_id = 0;
_notify_thread_continue = false;

View File

@ -1,4 +1,4 @@
// Filename: p3dToplevelObject.cxx
// Filename: p3dMainObject.cxx
// Created by: drose (10Jul09)
//
////////////////////////////////////////////////////////////////////
@ -12,26 +12,26 @@
//
////////////////////////////////////////////////////////////////////
#include "p3dToplevelObject.h"
#include "p3dMainObject.h"
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::Constructor
// Function: P3DMainObject::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
P3DToplevelObject::
P3DToplevelObject() :
P3DMainObject::
P3DMainObject() :
_pyobj(NULL)
{
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::Destructor
// Function: P3DMainObject::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
P3DToplevelObject::
~P3DToplevelObject() {
P3DMainObject::
~P3DMainObject() {
set_pyobj(NULL);
// Clear the local properties.
@ -44,58 +44,58 @@ P3DToplevelObject::
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_type
// Function: P3DMainObject::get_type
// Access: Public, Virtual
// Description: Returns the fundamental type of this kind of object.
////////////////////////////////////////////////////////////////////
P3D_object_type P3DToplevelObject::
P3D_object_type P3DMainObject::
get_type() {
return P3D_OT_object;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_bool
// Function: P3DMainObject::get_bool
// Access: Public, Virtual
// Description: Returns the object value coerced to a boolean, if
// possible.
////////////////////////////////////////////////////////////////////
bool P3DToplevelObject::
bool P3DMainObject::
get_bool() {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_int
// Function: P3DMainObject::get_int
// Access: Public, Virtual
// Description: Returns the object value coerced to an integer, if
// possible.
////////////////////////////////////////////////////////////////////
int P3DToplevelObject::
int P3DMainObject::
get_int() {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_float
// Function: P3DMainObject::get_float
// Access: Public, Virtual
// Description: Returns the object value coerced to a floating-point
// value, if possible.
////////////////////////////////////////////////////////////////////
double P3DToplevelObject::
double P3DMainObject::
get_float() {
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::make_string
// Function: P3DMainObject::make_string
// Access: Public, Virtual
// Description: Fills the indicated C++ string object with the value
// of this object coerced to a string.
////////////////////////////////////////////////////////////////////
void P3DToplevelObject::
void P3DMainObject::
make_string(string &value) {
if (_pyobj == NULL) {
value = "P3DToplevelObject";
value = "P3DMainObject";
} else {
int size = P3D_OBJECT_GET_STRING(_pyobj, NULL, 0);
char *buffer = new char[size];
@ -106,13 +106,13 @@ make_string(string &value) {
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_property
// Function: P3DMainObject::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::
P3D_object *P3DMainObject::
get_property(const string &property) {
if (_pyobj == NULL) {
// Without a pyobj, we just report whatever's been stored locally.
@ -131,13 +131,13 @@ get_property(const string &property) {
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::set_property
// Function: P3DMainObject::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::
bool P3DMainObject::
set_property(const string &property, P3D_object *value) {
// First, we set the property locally.
if (value != NULL) {
@ -171,12 +171,12 @@ set_property(const string &property, P3D_object *value) {
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::has_method
// Function: P3DMainObject::has_method
// Access: Public, Virtual
// Description: Returns true if the named method exists on this
// object, false otherwise.
////////////////////////////////////////////////////////////////////
bool P3DToplevelObject::
bool P3DMainObject::
has_method(const string &method_name) {
if (_pyobj == NULL) {
// No methods until we get our pyobj.
@ -187,7 +187,7 @@ has_method(const string &method_name) {
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::call
// Function: P3DMainObject::call
// Access: Public, Virtual
// Description: Invokes the named method on the object, passing the
// indicated parameters. If the method name is empty,
@ -199,7 +199,7 @@ has_method(const string &method_name) {
// value is always NULL, and there is no way to
// determine success or failure.
////////////////////////////////////////////////////////////////////
P3D_object *P3DToplevelObject::
P3D_object *P3DMainObject::
call(const string &method_name, bool needs_response,
P3D_object *params[], int num_params) {
if (_pyobj == NULL) {
@ -212,28 +212,28 @@ call(const string &method_name, bool needs_response,
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::output
// Function: P3DMainObject::output
// Access: Public, Virtual
// Description: Writes a formatted representation of the value to the
// indicated string. This is intended for developer
// assistance.
////////////////////////////////////////////////////////////////////
void P3DToplevelObject::
void P3DMainObject::
output(ostream &out) {
out << "P3DToplevelObject";
out << "P3DMainObject";
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::set_pyobj
// Function: P3DMainObject::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
// main object there. The new object's reference
// count is incremented, and the previous object's is
// decremented.
////////////////////////////////////////////////////////////////////
void P3DToplevelObject::
void P3DMainObject::
set_pyobj(P3D_object *pyobj) {
if (_pyobj != pyobj) {
P3D_OBJECT_XDECREF(_pyobj);
@ -254,12 +254,12 @@ set_pyobj(P3D_object *pyobj) {
}
////////////////////////////////////////////////////////////////////
// Function: P3DToplevelObject::get_pyobj
// Function: P3DMainObject::get_pyobj
// Access: Public
// Description: Returns the internal pyobj pointer, or NULL if it has
// not yet been set.
////////////////////////////////////////////////////////////////////
P3D_object *P3DToplevelObject::
P3D_object *P3DMainObject::
get_pyobj() const {
return _pyobj;
}

View File

@ -1,4 +1,4 @@
// Filename: p3dToplevelObject.h
// Filename: p3dMainObject.h
// Created by: drose (10Jul09)
//
////////////////////////////////////////////////////////////////////
@ -12,8 +12,8 @@
//
////////////////////////////////////////////////////////////////////
#ifndef P3DTOPLEVELOBJECT_H
#define P3DTOPLEVELOBJECT_H
#ifndef P3DMAINOBJECT_H
#define P3DMAINOBJECT_H
#include "p3d_plugin_common.h"
#include "p3dObject.h"
@ -22,10 +22,13 @@
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().
// Class : P3DMainObject
// Description : This corresponds to the "main" object exposed by a
// particular instance, as returned by
// P3DInstance::get_panda_script_object(). This object
// corresponds to the appRunner.main object in Python,
// and the document.pluginobject.main object in
// JavaScript.
//
// This is mostly a wrapper around a P3DPythonObject
// pointer, and therefore functions like any other
@ -35,10 +38,10 @@ class P3DSession;
// generated directly by the core API (like
// downloadProgress and such).
////////////////////////////////////////////////////////////////////
class P3DToplevelObject : public P3DObject {
class P3DMainObject : public P3DObject {
public:
P3DToplevelObject();
virtual ~P3DToplevelObject();
P3DMainObject();
virtual ~P3DMainObject();
public:
virtual P3D_object_type get_type();

View File

@ -330,14 +330,19 @@ got_desc_file(TiXmlDocument *doc, bool freshly_downloaded) {
extract = extract->NextSiblingElement("extract");
}
// Verify all of the extracts.
// Verify the uncompressed archive.
bool all_extracts_ok = true;
if (!_uncompressed_archive.quick_verify(_package_dir)) {
nout << "File is incorrect: " << _uncompressed_archive.get_filename() << "\n";
all_extracts_ok = false;
}
// Verify all of the extracts.
Extracts::iterator ci;
for (ci = _extracts.begin(); ci != _extracts.end(); ++ci) {
for (ci = _extracts.begin(); ci != _extracts.end() && all_extracts_ok; ++ci) {
if (!(*ci).quick_verify(_package_dir)) {
nout << "File is incorrect: " << (*ci).get_filename() << "\n";
all_extracts_ok = false;
break;
}
}

View File

@ -22,7 +22,7 @@
#include "p3dSplashWindow.cxx"
#include "p3dStringObject.cxx"
#include "p3dTemporaryFile.cxx"
#include "p3dToplevelObject.cxx"
#include "p3dMainObject.cxx"
#include "p3dUndefinedObject.cxx"
#include "p3dWinSplashWindow.cxx"
#include "p3dX11SplashWindow.cxx"

View File

@ -21,6 +21,7 @@
ppDownloadRequest.h ppDownloadRequest.I \
ppInstance.h ppInstance.I \
ppPandaObject.h ppPandaObject.I \
ppToplevelObject.h ppToplevelObject.I \
startup.h
#define INCLUDED_SOURCES \
@ -28,6 +29,7 @@
ppDownloadRequest.cxx \
ppInstance.cxx \
ppPandaObject.cxx \
ppToplevelObject.cxx \
startup.cxx
// Windows-specific options.

View File

@ -2,6 +2,7 @@
#include "ppDownloadRequest.cxx"
#include "ppInstance.cxx"
#include "ppPandaObject.cxx"
#include "ppToplevelObject.cxx"
#include "startup.cxx"

View File

@ -28,7 +28,8 @@ public:
enum RequestType {
RT_contents_file,
RT_core_dll,
RT_user
RT_user,
RT_instance_data
};
inline PPDownloadRequest(RequestType rtype, int user_id = 0);

View File

@ -14,6 +14,7 @@
#include "ppInstance.h"
#include "ppPandaObject.h"
#include "ppToplevelObject.h"
#include "ppBrowserObject.h"
#include "startup.h"
#include "p3d_plugin_config.h"
@ -73,7 +74,6 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
////////////////////////////////////////////////////////////////////
PPInstance::
~PPInstance() {
nout << "Destructing PPInstance\n";
cleanup_window();
if (_p3d_inst != NULL) {
@ -187,7 +187,17 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) {
_instance_url = stream->url;
if (_p3d_inst != NULL) {
P3D_instance_start(_p3d_inst, false, _instance_url.c_str());
}
}
// We don't want the rest of this stream any more, but we can't
// just return NPERR_GENERIC_ERROR, though--that seems to freak
// out Mozilla. Instead, we'll "accept" it for now, and then
// immediately stop it when we get the first write_stream()
// call.
stream->notifyData = new PPDownloadRequest(PPDownloadRequest::RT_instance_data);
*stype = NP_NORMAL;
return NPERR_NO_ERROR;
}
// Don't finish downloading the unsolicited stream.
@ -232,6 +242,7 @@ int PPInstance::
write_stream(NPStream *stream, int offset, int len, void *buffer) {
if (stream->notifyData == NULL) {
nout << "Unexpected write_stream on " << stream->url << "\n";
browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK);
return 0;
}
@ -242,12 +253,18 @@ write_stream(NPStream *stream, int offset, int len, void *buffer) {
P3D_RC_in_progress, 0,
stream->end, buffer, len);
return len;
case PPDownloadRequest::RT_instance_data:
// Here's a stream we don't really want.
browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK);
return 0;
default:
nout << "Unexpected write_stream on " << stream->url << "\n";
break;
}
browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK);
return 0;
}
@ -262,7 +279,7 @@ NPError PPInstance::
destroy_stream(NPStream *stream, NPReason reason) {
if (stream->notifyData == NULL) {
nout << "Unexpected destroy_stream on " << stream->url << "\n";
return NPERR_GENERIC_ERROR;
return NPERR_NO_ERROR;
}
PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
@ -280,10 +297,16 @@ destroy_stream(NPStream *stream, NPReason reason) {
}
break;
case PPDownloadRequest::RT_instance_data:
// We won't get a url_notify on this one, so delete it now.
delete req;
break;
default:
nout << "Unexpected destroy_stream on " << stream->url << "\n";
break;
}
return NPERR_NO_ERROR;
}
@ -333,6 +356,7 @@ url_notify(const char *url, NPReason reason, void *notifyData) {
break;
default:
nout << "Unexpected url_notify on stream type " << req->_rtype << "\n";
break;
}
@ -539,13 +563,14 @@ get_panda_script_object() {
return _script_object;
}
P3D_object *obj = NULL;
P3D_object *main = NULL;
if (_p3d_inst != NULL) {
obj = P3D_instance_get_panda_script_object(_p3d_inst);
main = P3D_instance_get_panda_script_object(_p3d_inst);
}
_script_object = PPPandaObject::make_new(this, obj);
_script_object = PPToplevelObject::make_new(this);
_script_object->set_main(main);
browser->retainobject(_script_object);
return _script_object;
@ -975,8 +1000,8 @@ create_instance() {
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);
P3D_object *main = P3D_instance_get_panda_script_object(_p3d_inst);
_script_object->set_main(main);
}
if (_got_instance_url) {
@ -1069,7 +1094,6 @@ send_window() {
// No size: hidden.
window_type = P3D_WT_hidden;
}
nout << "window_type = " << window_type << "\n";
P3D_instance_setup_window
(_p3d_inst, window_type,
@ -1090,7 +1114,6 @@ cleanup_window() {
// Restore the parent window to its own window handler.
HWND hwnd = (HWND)_window.window;
SetWindowLongPtr(hwnd, GWL_WNDPROC, _orig_window_proc);
nout << "Restored window handler for " << hwnd << "\n";
InvalidateRect(hwnd, NULL, true);
#endif // _WIN32
_got_window = false;

View File

@ -22,7 +22,7 @@
#include <vector>
class PPPandaObject;
class PPToplevelObject;
class PPDownloadRequest;
////////////////////////////////////////////////////////////////////
@ -140,7 +140,7 @@ private:
bool _python_window_open;
PPPandaObject *_script_object;
PPToplevelObject *_script_object;
P3D_instance *_p3d_inst;
};

View File

@ -0,0 +1,14 @@
// Filename: ppToplevelObject.I
// Created by: drose (21Aug09)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,276 @@
// Filename: ppToplevelObject.cxx
// Created by: drose (21Aug09)
//
////////////////////////////////////////////////////////////////////
//
// 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 "ppToplevelObject.h"
NPClass PPToplevelObject::_object_class = {
NP_CLASS_STRUCT_VERSION,
&PPToplevelObject::NPAllocate,
&PPToplevelObject::NPDeallocate,
&PPToplevelObject::NPInvalidate,
&PPToplevelObject::NPHasMethod,
&PPToplevelObject::NPInvoke,
&PPToplevelObject::NPInvokeDefault,
&PPToplevelObject::NPHasProperty,
&PPToplevelObject::NPGetProperty,
&PPToplevelObject::NPSetProperty,
&PPToplevelObject::NPRemoveProperty,
#if defined(NP_CLASS_STRUCT_VERSION_ENUM) && NP_CLASS_STRUCT_VERSION >= NP_CLASS_STRUCT_VERSION_ENUM
&PPToplevelObject::NPEnumerate,
#endif
#if defined(NP_CLASS_STRUCT_VERSION_CTOR) && NP_CLASS_STRUCT_VERSION >= NP_CLASS_STRUCT_VERSION_CTOR
&PPToplevelObject::NPConstruct,
#endif
};
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::make_new
// Access: Public, Static
// Description: Use this call to construct a new PPToplevelObject.
////////////////////////////////////////////////////////////////////
PPToplevelObject *PPToplevelObject::
make_new(PPInstance *inst) {
NPObject *npobj =
browser->createobject(inst->get_npp_instance(), &_object_class);
PPToplevelObject *ppobj = (PPToplevelObject *)npobj;
ppobj->construct(inst);
return ppobj;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::set_main
// Access: Public
// Description: Changes the "main" object this PPToplevelObject maps
// to. The new object's reference count is incremented,
// and the previous object's is decremented.
////////////////////////////////////////////////////////////////////
void PPToplevelObject::
set_main(P3D_object *p3d_object) {
if (p3d_object != NULL) {
P3D_OBJECT_INCREF(p3d_object);
}
P3D_OBJECT_XDECREF(_main);
_main = p3d_object;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::construct
// Access: Private
// Description: Stands in for the C++ constructor. We can't have a
// true constructor because of the C-style interface in
// NPN_CreateObject(). This must be called explicitly
// following NPN_CreateObject().
////////////////////////////////////////////////////////////////////
void PPToplevelObject::
construct(PPInstance *inst) {
_instance = inst;
_main = NULL;
// Get our one property name as an identifier, so we can look for
// it.
_main_id = browser->getstringidentifier("main");
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::invalidate
// Access: Private
// Description: This "destructor" is called by NPInvalidate().
////////////////////////////////////////////////////////////////////
void PPToplevelObject::
invalidate() {
_instance = NULL;
set_main(NULL);
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::has_property
// Access: Private
// Description: Returns true if the object has the named property,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
has_property(NPIdentifier name) {
if (_main == NULL) {
// Not powered up yet.
return false;
}
if (name == _main_id) {
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::get_property
// Access: Private
// Description: Retrieves the named property value from the object
// and stores it in result. Returns true on success,
// false on failure.
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
get_property(NPIdentifier name, NPVariant *result) {
if (_main == NULL) {
// Not powered up yet.
return false;
}
if (name == _main_id) {
_instance->p3dobj_to_variant(result, _main);
return true;
}
return false;
}
// The remaining function bodies are the C-style function wrappers
// that are called directly by NPAPI, and which redirect into the
// above C++-style methods.
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPAllocate
// Access: Private, Static
// Description: Called by NPN_CreateObject() to allocate space for
// this object.
////////////////////////////////////////////////////////////////////
NPObject *PPToplevelObject::
NPAllocate(NPP npp, NPClass *aClass) {
assert(aClass == &_object_class);
return (PPToplevelObject *)malloc(sizeof(PPToplevelObject));
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::Deallocate
// Access: Private, Static
// Description: Called to delete the space allocated by NPAllocate,
// above.
////////////////////////////////////////////////////////////////////
void PPToplevelObject::
NPDeallocate(NPObject *npobj) {
((PPToplevelObject *)npobj)->invalidate();
free(npobj);
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::Deallocate
// Access: Private, Static
// Description: Called to destruct the object.
////////////////////////////////////////////////////////////////////
void PPToplevelObject::
NPInvalidate(NPObject *npobj) {
// It turns out that this method isn't actually called by Safari's
// implementation of NPAPI, so we'll move the actual destructor call
// into NPDeallocate, above.
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPHasMethod
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPHasMethod(NPObject *npobj, NPIdentifier name) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPInvoke
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPInvoke(NPObject *npobj, NPIdentifier name,
const NPVariant *args, uint32_t argCount,
NPVariant *result) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPInvokeDefault
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPInvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount,
NPVariant *result) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPHasProperty
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPHasProperty(NPObject *npobj, NPIdentifier name) {
return ((PPToplevelObject *)npobj)->has_property(name);
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPGetProperty
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) {
return ((PPToplevelObject *)npobj)->get_property(name, result);
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPSetProperty
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPRemoveProperty
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPRemoveProperty(NPObject *npobj, NPIdentifier name) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPEnumerate
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPToplevelObject::NPConstruct
// Access: Private, Static
// Description:
////////////////////////////////////////////////////////////////////
bool PPToplevelObject::
NPConstruct(NPObject *npobj, const NPVariant *args,
uint32_t argCount, NPVariant *result) {
// Not implemented. We don't use this constructor mechanism because
// it wasn't supported on earlier versions of Gecko. Instead, we
// use make_new() to construct PPToplevelObjects via an explicit call to
// construct().
return true;
}

View File

@ -0,0 +1,80 @@
// Filename: ppToplevelObject.h
// Created by: drose (21Aug09)
//
////////////////////////////////////////////////////////////////////
//
// 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 PPTOPLEVELOBJECT_H
#define PPTOPLEVELOBJECT_H
#include "nppanda3d_common.h"
////////////////////////////////////////////////////////////////////
// Class : PPToplevelObject
// Description : This is a special object fed to Mozilla as the
// toplevel scripting object for the instance. It has
// only one property, "main", which corresponds to the
// appRunner.main object from Python.
////////////////////////////////////////////////////////////////////
class PPToplevelObject : public NPObject {
public:
static PPToplevelObject *make_new(PPInstance *inst);
inline P3D_object *get_main() const;
void set_main(P3D_object *main);
private:
void construct(PPInstance *inst);
void invalidate();
bool has_property(NPIdentifier name);
bool get_property(NPIdentifier name,
NPVariant *result);
private:
static NPObject *NPAllocate(NPP npp, NPClass *aClass);
static void NPDeallocate(NPObject *npobj);
static void NPInvalidate(NPObject *npobj);
static bool NPHasMethod(NPObject *npobj, NPIdentifier name);
static bool NPInvoke(NPObject *npobj, NPIdentifier name,
const NPVariant *args, uint32_t argCount,
NPVariant *result);
static bool NPInvokeDefault(NPObject *npobj,
const NPVariant *args,
uint32_t argCount,
NPVariant *result);
static bool NPHasProperty(NPObject *npobj, NPIdentifier name);
static bool NPGetProperty(NPObject *npobj, NPIdentifier name,
NPVariant *result);
static bool NPSetProperty(NPObject *npobj, NPIdentifier name,
const NPVariant *value);
static bool NPRemoveProperty(NPObject *npobj,
NPIdentifier name);
static bool NPEnumerate(NPObject *npobj, NPIdentifier **value,
uint32_t *count);
static bool NPConstruct(NPObject *npobj,
const NPVariant *args,
uint32_t argCount,
NPVariant *result);
private:
PPInstance *_instance;
P3D_object *_main;
NPIdentifier _main_id;
public:
static NPClass _object_class;
};
#include "ppToplevelObject.I"
#endif