ditch the P3DListObject

This commit is contained in:
David Rose 2009-07-05 15:54:53 +00:00
parent f33032dd6b
commit 47e364b1e1
15 changed files with 114 additions and 551 deletions

View File

@ -29,7 +29,6 @@
p3dInstance.h p3dInstance.I \
p3dInstanceManager.h p3dInstanceManager.I \
p3dIntObject.h \
p3dListObject.h \
p3dMultifileReader.h p3dMultifileReader.I \
p3dPackage.h p3dPackage.I \
p3dPythonObject.h \
@ -51,7 +50,6 @@
p3dInstance.cxx \
p3dInstanceManager.cxx \
p3dIntObject.cxx \
p3dListObject.cxx \
p3dMultifileReader.cxx \
p3dPackage.cxx \
p3dPythonObject.cxx \

View File

@ -46,7 +46,6 @@ P3D_new_bool_object_func *P3D_new_bool_object;
P3D_new_int_object_func *P3D_new_int_object;
P3D_new_float_object_func *P3D_new_float_object;
P3D_new_string_object_func *P3D_new_string_object;
P3D_new_list_object_func *P3D_new_list_object;
P3D_instance_get_script_object_func *P3D_instance_get_script_object;
P3D_instance_set_script_object_func *P3D_instance_set_script_object;
@ -189,7 +188,6 @@ load_plugin(const string &p3d_plugin_filename) {
P3D_new_int_object = (P3D_new_int_object_func *)get_func(module, "P3D_new_int_object");
P3D_new_float_object = (P3D_new_float_object_func *)get_func(module, "P3D_new_float_object");
P3D_new_string_object = (P3D_new_string_object_func *)get_func(module, "P3D_new_string_object");
P3D_new_list_object = (P3D_new_list_object_func *)get_func(module, "P3D_new_list_object");
P3D_instance_get_script_object = (P3D_instance_get_script_object_func *)get_func(module, "P3D_instance_get_script_object");
P3D_instance_set_script_object = (P3D_instance_set_script_object_func *)get_func(module, "P3D_instance_set_script_object");
@ -214,7 +212,6 @@ load_plugin(const string &p3d_plugin_filename) {
P3D_new_int_object == NULL ||
P3D_new_float_object == NULL ||
P3D_new_string_object == NULL ||
P3D_new_list_object == NULL ||
P3D_instance_get_script_object == NULL ||
P3D_instance_set_script_object == NULL ||
@ -238,7 +235,6 @@ load_plugin(const string &p3d_plugin_filename) {
<< "\nP3D_new_int_object = " << P3D_new_int_object
<< "\nP3D_new_float_object = " << P3D_new_float_object
<< "\nP3D_new_string_object = " << P3D_new_string_object
<< "\nP3D_new_list_object = " << P3D_new_list_object
<< "\nP3D_instance_get_script_object = " << P3D_instance_get_script_object
<< "\nP3D_instance_set_script_object = " << P3D_instance_set_script_object
@ -317,7 +313,6 @@ unload_dso() {
P3D_new_int_object = NULL;
P3D_new_float_object = NULL;
P3D_new_string_object = NULL;
P3D_new_list_object = NULL;
P3D_instance_get_script_object = NULL;
P3D_instance_set_script_object = NULL;

View File

@ -33,7 +33,6 @@ extern P3D_new_bool_object_func *P3D_new_bool_object;
extern P3D_new_int_object_func *P3D_new_int_object;
extern P3D_new_float_object_func *P3D_new_float_object;
extern P3D_new_string_object_func *P3D_new_string_object;
extern P3D_new_list_object_func *P3D_new_list_object;
extern P3D_instance_get_script_object_func *P3D_instance_get_script_object;
extern P3D_instance_set_script_object_func *P3D_instance_set_script_object;

View File

@ -1,199 +0,0 @@
// Filename: p3dListObject.cxx
// Created by: drose (30Jun09)
//
////////////////////////////////////////////////////////////////////
//
// 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 "p3dListObject.h"
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
P3DListObject::
P3DListObject() {
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
P3DListObject::
P3DListObject(const P3DListObject &copy) :
P3DObject(copy)
{
_elements.reserve(copy._elements.size());
Elements::const_iterator ei;
for (ei = copy._elements.begin(); ei != copy._elements.end(); ++ei) {
_elements.push_back(P3D_OBJECT_COPY(*ei));
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
P3DListObject::
~P3DListObject() {
Elements::iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
P3D_OBJECT_FINISH(*ei);
}
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::make_copy
// Access: Public, Virtual
// Description: Returns a new copy of the object, if necessary. If
// the object type is static and all instances are
// identical, this actually simply ups the reference
// count and returns the same object.
////////////////////////////////////////////////////////////////////
P3DObject *P3DListObject::
make_copy() const {
return new P3DListObject(*this);
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::get_type
// Access: Public, Virtual
// Description: Returns the fundamental type of this kind of object.
////////////////////////////////////////////////////////////////////
P3D_object_type P3DListObject::
get_type() const {
return P3D_OT_list;
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::get_bool
// Access: Public, Virtual
// Description: Returns the object value coerced to a boolean, if
// possible.
////////////////////////////////////////////////////////////////////
bool P3DListObject::
get_bool() const {
return !_elements.empty();
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::make_string
// Access: Public, Virtual
// Description: Fills the indicated C++ string object with the value
// of this object coerced to a string.
////////////////////////////////////////////////////////////////////
void P3DListObject::
make_string(string &value) const {
ostringstream strm;
strm << "[";
if (!_elements.empty()) {
strm << *_elements[0];
for (size_t i = 1; i < _elements.size(); ++i) {
strm << ", " << *_elements[i];
}
}
strm << "]";
value = strm.str();
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::get_list_length
// Access: Public, Virtual
// Description: Returns the length of the object as a list.
////////////////////////////////////////////////////////////////////
int P3DListObject::
get_list_length() const {
return _elements.size();
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::get_element
// Access: Public, Virtual
// Description: Returns the nth item in the value as a list. The
// return value is a freshly-allocated P3DObject object
// that must be deleted by the caller, or NULL on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DListObject::
get_element(int n) const {
if (n >= 0 && n < (int)_elements.size()) {
return P3D_OBJECT_COPY(_elements[n]);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::set_element
// Access: Public, Virtual
// Description: Modifies (or deletes, if value is NULL) the nth item
// in the value as a list. Returns true on success,
// false on failure.
////////////////////////////////////////////////////////////////////
bool P3DListObject::
set_element(int n, P3D_object *value) {
if (n < 0 || n > (int)_elements.size()) {
// Invalid index.
return false;
}
if (n == _elements.size()) {
// Append one.
_elements.push_back(NULL);
}
if (_elements[n] != NULL) {
// Delete prior.
P3D_OBJECT_FINISH(_elements[n]);
}
_elements[n] = value;
// Delete NULL elements on the end.
while (!_elements.empty() && _elements.back() == NULL) {
_elements.pop_back();
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::append
// Access: Public, Virtual
// Description: Adds a new element to the end of the list. Ownership
// is transferred to the list.
////////////////////////////////////////////////////////////////////
void P3DListObject::
append(P3D_object *value) {
_elements.push_back(value);
}
////////////////////////////////////////////////////////////////////
// Function: P3DListObject::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this value.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DListObject::
make_xml() const {
TiXmlElement *xvalue = new TiXmlElement("value");
xvalue->SetAttribute("type", "list");
Elements::const_iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
P3D_object *child = (*ei);
assert(child->_class == &P3DObject::_object_class);
TiXmlElement *xchild = ((P3DObject *)child)->make_xml();
xvalue->LinkEndChild(xchild);
}
return xvalue;
}

View File

@ -1,51 +0,0 @@
// Filename: p3dListObject.h
// Created by: drose (30Jun09)
//
////////////////////////////////////////////////////////////////////
//
// 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 P3DLISTOBJECT_H
#define P3DLISTOBJECT_H
#include "p3d_plugin_common.h"
#include "p3dObject.h"
////////////////////////////////////////////////////////////////////
// Class : P3DListObject
// Description : An object type that contains a list of objects.
////////////////////////////////////////////////////////////////////
class P3DListObject : public P3DObject {
public:
P3DListObject();
P3DListObject(const P3DListObject &copy);
public:
virtual ~P3DListObject();
virtual P3DObject *make_copy() const;
virtual P3D_object_type get_type() const;
virtual bool get_bool() const;
virtual void make_string(string &value) const;
virtual int get_list_length() const;
virtual P3D_object *get_element(int n) const;
virtual bool set_element(int n, P3D_object *value);
void append(P3D_object *value);
virtual TiXmlElement *make_xml() const;
private:
typedef vector<P3D_object *> Elements;
Elements _elements;
};
#endif

View File

@ -70,27 +70,13 @@ object_set_property(P3D_object *object, const char *property,
return ((P3DObject *)object)->set_property(property, value);
}
static P3D_object *
object_get_element(const P3D_object *object, int n) {
return ((const P3DObject *)object)->get_element(n);
}
static bool
object_set_element(P3D_object *object, int n, P3D_object *value) {
return ((P3DObject *)object)->set_element(n, value);
}
static int object_get_list_length(const P3D_object *object) {
return ((const P3DObject *)object)->get_list_length();
}
static P3D_object *
object_call(const P3D_object *object, const char *method_name,
P3D_object *params) {
P3D_object *params[], int num_params) {
if (method_name == NULL) {
method_name = "";
}
return ((const P3DObject *)object)->call(method_name, params);
return ((const P3DObject *)object)->call(method_name, params, num_params);
}
P3D_class_definition P3DObject::_object_class = {
@ -104,9 +90,6 @@ P3D_class_definition P3DObject::_object_class = {
&object_get_repr,
&object_get_property,
&object_set_property,
&object_get_element,
&object_set_element,
&object_get_list_length,
&object_call,
};
@ -215,43 +198,6 @@ set_property(const string &property, P3D_object *value) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::get_list_length
// Access: Public, Virtual
// Description: Returns the length of the object as a list.
////////////////////////////////////////////////////////////////////
int P3DObject::
get_list_length() const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::get_element
// Access: Public, Virtual
// Description: Returns the nth item in the value as a list. The
// return value is a freshly-allocated P3DObject object
// that must be deleted by the caller, or NULL on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DObject::
get_element(int n) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::set_element
// Access: Public, Virtual
// Description: Modifies (or deletes, if value is NULL) the nth item
// in the value as a list. Returns true on success,
// false on failure.
////////////////////////////////////////////////////////////////////
bool P3DObject::
set_element(int n, P3D_object *value) {
if (value != NULL) {
P3D_OBJECT_FINISH(value);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: P3DObject::call
// Access: Public, Virtual
@ -261,9 +207,9 @@ set_element(int n, P3D_object *value) {
// on success, NULL on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DObject::
call(const string &method_name, P3D_object *params) const {
if (params != NULL) {
P3D_OBJECT_FINISH(params);
call(const string &method_name, P3D_object *params[], int num_params) const {
for (int i = 0; i < num_params; ++i) {
P3D_OBJECT_FINISH(params[i]);
}
return NULL;
}

View File

@ -46,11 +46,8 @@ public:
virtual P3D_object *get_property(const string &property) const;
virtual bool set_property(const string &property, P3D_object *value);
virtual int get_list_length() const;
virtual P3D_object *get_element(int n) const;
virtual bool set_element(int n, P3D_object *value);
virtual P3D_object *call(const string &method_name, P3D_object *params) const;
virtual P3D_object *call(const string &method_name,
P3D_object *params[], int num_params) const;
virtual TiXmlElement *make_xml() const=0;

View File

@ -56,7 +56,7 @@ bool P3DPythonObject::
get_bool() const {
bool bresult = 0;
P3D_object *result = call("__bool__", NULL);
P3D_object *result = call("__bool__", NULL, 0);
if (result != NULL) {
bresult = P3D_OBJECT_GET_BOOL(result);
P3D_OBJECT_FINISH(result);
@ -75,7 +75,7 @@ int P3DPythonObject::
get_int() const {
int iresult = 0;
P3D_object *result = call("__int__", NULL);
P3D_object *result = call("__int__", NULL, 0);
if (result != NULL) {
iresult = P3D_OBJECT_GET_INT(result);
P3D_OBJECT_FINISH(result);
@ -94,7 +94,7 @@ double P3DPythonObject::
get_float() const {
double fresult = 0.0;
P3D_object *result = call("__float__", NULL);
P3D_object *result = call("__float__", NULL, 0);
if (result != NULL) {
fresult = P3D_OBJECT_GET_FLOAT(result);
P3D_OBJECT_FINISH(result);
@ -111,7 +111,7 @@ get_float() const {
////////////////////////////////////////////////////////////////////
void P3DPythonObject::
make_string(string &value) const {
P3D_object *result = call("__str__", NULL);
P3D_object *result = call("__str__", NULL, 0);
if (result != NULL) {
int size = P3D_OBJECT_GET_STRING(result, NULL, 0);
char *buffer = new char[size];
@ -132,10 +132,10 @@ make_string(string &value) const {
////////////////////////////////////////////////////////////////////
P3D_object *P3DPythonObject::
get_property(const string &property) const {
P3DListObject *params = new P3DListObject;
params->append(new P3DStringObject(property));
P3D_object *params[1];
params[0] = new P3DStringObject(property);
P3D_object *result = call("__getattr__", params);
P3D_object *result = call("__getattr__", params, 1);
return result;
}
@ -150,20 +150,19 @@ bool P3DPythonObject::
set_property(const string &property, P3D_object *value) {
bool bresult = false;
P3DListObject *params = new P3DListObject;
params->append(new P3DStringObject(property));
P3D_object *params[2];
params[0] = new P3DStringObject(property);
P3D_object *result = NULL;
if (value == NULL) {
// Delete an attribute.
result = call("__delattr__", params);
result = call("__delattr__", params, 1);
} else {
// Set a new attribute.
params->append(value);
result = call("__setattr__", params);
params[1] = value;
result = call("__setattr__", params, 2);
}
if (result != NULL) {
@ -174,46 +173,6 @@ set_property(const string &property, P3D_object *value) {
return bresult;
}
////////////////////////////////////////////////////////////////////
// Function: P3DPythonObject::get_list_length
// Access: Public, Virtual
// Description: Returns the length of the object as a list.
////////////////////////////////////////////////////////////////////
int P3DPythonObject::
get_list_length() const {
// TODO.
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: P3DPythonObject::get_element
// Access: Public, Virtual
// Description: Returns the nth item in the value as a list. The
// return value is a freshly-allocated P3DPythonObject object
// that must be deleted by the caller, or NULL on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DPythonObject::
get_element(int n) const {
// TODO.
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: P3DPythonObject::set_element
// Access: Public, Virtual
// Description: Modifies (or deletes, if value is NULL) the nth item
// in the value as a list. Returns true on success,
// false on failure.
////////////////////////////////////////////////////////////////////
bool P3DPythonObject::
set_element(int n, P3D_object *value) {
// TODO.
if (value != NULL) {
P3D_OBJECT_FINISH(value);
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: P3DPythonObject::call
// Access: Public, Virtual
@ -223,7 +182,7 @@ set_element(int n, P3D_object *value) {
// on success, NULL on error.
////////////////////////////////////////////////////////////////////
P3D_object *P3DPythonObject::
call(const string &method_name, P3D_object *params) const {
call(const string &method_name, P3D_object *params[], int num_params) const {
TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command");
@ -234,14 +193,14 @@ call(const string &method_name, P3D_object *params) const {
xcommand->SetAttribute("method_name", method_name);
}
if (params != NULL) {
assert(params->_class == &P3DObject::_object_class);
TiXmlElement *xparams = ((P3DObject *)params)->make_xml();
for (int i = 0; i < num_params; ++i) {
assert(params[i]->_class == &P3DObject::_object_class);
TiXmlElement *xparams = ((P3DObject *)params[i])->make_xml();
xcommand->LinkEndChild(xparams);
// Now we're done with the params object passed in, we can delete
// it as promised.
P3D_OBJECT_FINISH(params);
P3D_OBJECT_FINISH(params[i]);
}
doc->LinkEndChild(decl);
@ -277,7 +236,7 @@ call(const string &method_name, P3D_object *params) const {
////////////////////////////////////////////////////////////////////
void P3DPythonObject::
output(ostream &out) const {
P3D_object *result = call("__repr__", NULL);
P3D_object *result = call("__repr__", NULL, 0);
out << "Python " << _object_id;
if (result != NULL) {
out << ": " << *result;

View File

@ -44,11 +44,8 @@ public:
virtual P3D_object *get_property(const string &property) const;
virtual bool set_property(const string &property, P3D_object *value);
virtual int get_list_length() const;
virtual P3D_object *get_element(int n) const;
virtual bool set_element(int n, P3D_object *value);
virtual P3D_object *call(const string &method_name, P3D_object *params) const;
virtual P3D_object *call(const string &method_name,
P3D_object *params[], int num_params) const;
virtual TiXmlElement *make_xml() const;

View File

@ -286,21 +286,21 @@ handle_pyobj_command(TiXmlElement *xcommand, int want_response_id) {
if (xcommand->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {
PyObject *obj = (PyObject *)(void *)object_id;
const char *method_name = xcommand->Attribute("method_name");
PyObject *params = NULL;
TiXmlElement *xvalue = xcommand->FirstChildElement("value");
if (xvalue != NULL) {
params = xml_to_pyobj(xvalue);
if (!PySequence_Check(params)) {
// Wrap it in a tuple to pass it to the method.
PyObject *tuple = PyTuple_New(1);
PyTuple_SetItem(tuple, 0, params);
params = tuple;
}
// Build up a list of params.
PyObject *list = PyList_New(0);
TiXmlElement *xchild = xcommand->FirstChildElement("value");
while (xchild != NULL) {
PyObject *child = xml_to_pyobj(xchild);
PyList_Append(list, child);
Py_DECREF(child);
xchild = xchild->NextSiblingElement("value");
}
if (params == NULL) {
params = PyTuple_New(0);
}
// Convert the list to a tuple for the call.
PyObject *params = PyList_AsTuple(list);
Py_DECREF(list);
// Now call the method.
PyObject *result = NULL;
@ -772,20 +772,6 @@ pyobj_to_xml(PyObject *value) {
xvalue->SetAttribute("value", str);
}
} else if (PyTuple_CheckExact(value)) {
// A tuple. We check for this class type specifically; other
// objects that provide a sequence interface should be treated as
// generic Python objects, below, so we don't lose other useful
// functionality in these objects. Even a Python list, since we
// want to allow the caller to modify the list object on the
// Python side.
xvalue->SetAttribute("type", "list");
Py_ssize_t length = PySequence_Length(value);
for (Py_ssize_t i = 0; i < length; ++i) {
PyObject *obj = PySequence_GetItem(value, i);
xvalue->LinkEndChild(pyobj_to_xml(obj));
}
} else {
// Some other kind of object. Make it a generic Python object.
// This is more expensive for the caller to deal with--it requires
@ -839,20 +825,6 @@ xml_to_pyobj(TiXmlElement *xvalue) {
return PyString_FromStringAndSize(value->data(), value->length());
}
} else if (strcmp(type, "list") == 0) {
PyObject *list = PyList_New(0);
TiXmlElement *xchild = xvalue->FirstChildElement("value");
while (xchild != NULL) {
PyObject *child = xml_to_pyobj(xchild);
PyList_Append(list, child);
Py_DECREF(child);
xchild = xchild->NextSiblingElement("value");
}
PyObject *tuple = PyList_AsTuple(list);
Py_DECREF(list);
return tuple;
} else if (strcmp(type, "python") == 0) {
int object_id;
if (xvalue->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {

View File

@ -20,7 +20,6 @@
#include "p3dBoolObject.h"
#include "p3dIntObject.h"
#include "p3dFloatObject.h"
#include "p3dListObject.h"
#include "p3dPythonObject.h"
#ifndef _WIN32
@ -332,16 +331,6 @@ xml_to_object(TiXmlElement *xvalue) {
return new P3DStringObject(*value);
}
} else if (strcmp(type, "list") == 0) {
P3DListObject *list = new P3DListObject;
TiXmlElement *xchild = xvalue->FirstChildElement("value");
while (xchild != NULL) {
list->set_element(list->get_list_length(), xml_to_object(xchild));
xchild = xchild->NextSiblingElement("value");
}
return list;
} else if (strcmp(type, "python") == 0) {
int object_id;
if (xvalue->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {

View File

@ -21,7 +21,6 @@
#include "p3dIntObject.h"
#include "p3dFloatObject.h"
#include "p3dStringObject.h"
#include "p3dListObject.h"
#include <assert.h>
@ -188,17 +187,6 @@ P3D_new_string_object(const char *str, int length) {
return result;
}
P3D_object *
P3D_new_list_object() {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock);
P3D_object *result = new P3DListObject;
RELEASE_LOCK(_api_lock);
return result;
}
P3D_object *
P3D_instance_get_script_object(P3D_instance *instance) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized());

View File

@ -15,24 +15,25 @@
#ifndef P3D_PLUGIN_H
#define P3D_PLUGIN_H
/* This file defines the C-level API to Panda's plugin system. This
/* This file defines the C-level API to Panda's core plugin API. This
API is intended to provide basic functionality for loading and
running Panda's .p3d files, particularly within a browser.
running Panda's .p3d files, particularly within a browser.
This plugin code is intended to be loaded and run as a standalone
DLL. It will in turn be responsible for fetching and installing
the appropriate version of Panda and Python, as well as any
required supporting libraries.
This core API is intended to be loaded and run within a browser, as
a standalone DLL. It will in turn be responsible for fetching and
installing the appropriate version of Panda and Python, as well as
any required supporting libraries.
Note that this code defines only the interface between the actual
browser plugin and the Panda code. The actual plugin itself will
be a separate piece of code, written in ActiveX or NPIP or whatever
API is required for a given browser, which is designed to download
and link with this layer.
browser plugin and the Panda code. It contains no code to directly
interface with any browser. The actual plugin itself will be a
separate piece of code, written in ActiveX or NPAPI or whatever API
is required for a given browser; and this code will be designed to
download and link with this DLL.
The browser or launching application will be referred to as the
"host" in this documentation. The host should load this plugin dll
only once, but may then use it to create multiple simultaneous
"host" in this documentation. The host should load this core API
DLL only once, but may then use it to create multiple simultaneous
different instances of Panda windows.
Filenames passed through this interface are in native OS-specific
@ -65,8 +66,8 @@ extern "C" {
are finally declared at the end of this file, but only if
P3D_PLUGIN_PROTOTYPES is defined. This is intended to allow
including this file without building an implicit reference to the
functions themselves, allowing the plugin library to be loaded via
an explicit LoadLibrary() or equivalent call. */
functions themselves, allowing the core API library to be loaded
via an explicit LoadLibrary() or equivalent call. */
/* This symbol serves to validate that runtime and compile-time
@ -77,28 +78,28 @@ the interface specifications defined in this header file. */
/************************ GLOBAL FUNCTIONS **************************/
/* The following interfaces are global to the plugin space, as opposed
to being specific to a particular instance. */
/* The following interfaces are global to the core API space, as
opposed to being specific to a particular instance. */
/* This function should be called immediately after the plugin is
/* This function should be called immediately after the core API is
loaded. You should pass P3D_API_VERSION as the first parameter, so
the dll can verify that it has been built with the same version of
the DLL can verify that it has been built with the same version of
the API as the host.
The output_filename is usually NULL, but if you put a filename
here, it will be used as the log file for the output from the
plugin. This is useful for debugging, particularly when running
here, it will be used as the log file for the output from the core
API. This is useful for debugging, particularly when running
within a browser that squelches stderr.
This function returns true if the plugin is valid and uses a
This function returns true if the core API is valid and uses a
compatible API, false otherwise. If it returns false, the host
should not call any more functions in this API, and should
immediately unload the DLL and (if possible) download a new one. */
typedef bool
P3D_initialize_func(int api_version, const char *output_filename);
/* This function should be called to unload the plugin. It will
release all internally-allocated memory and return the plugin to
/* This function should be called to unload the core API. It will
release all internally-allocated memory and return the core API to
its initial state. */
typedef void
P3D_finalize_func();
@ -117,7 +118,7 @@ typedef struct {
bool _request_pending;
/* an opaque pointer the host may use to store private data that the
plugin does not interpret. This pointer can be directly set, or
core API does not interpret. This pointer can be directly set, or
it can be initialized in the P3D_new_instance() call. */
void *_user_data;
@ -141,28 +142,28 @@ typedef struct {
as a request only; it is always free to create whatever kind of
window it likes. */
typedef enum {
/* Embedded: the plugin window is embedded within the host window.
/* Embedded: the Panda window is embedded within the host window.
This is the normal kind of window for an object embedded within a
browser page. Pass a valid window handle in for parent_window,
and valid coordinates on the parent window for win_x, win_y,
win_width, win_height. */
P3D_WT_embedded,
/* Toplevel: the plugin window is a toplevel window on the user's
/* Toplevel: the Panda window is a toplevel window on the user's
desktop. Pass valid desktop coordinates in for win_x, win_y,
win_width, and win_height. If all of these are zero, the plugin
will create a window wherever it sees fit. */
win_width, and win_height. If all of these are zero, the core
API will create a window wherever it sees fit. */
P3D_WT_toplevel,
/* Fullscreen: the plugin window is a fullscreen window, completely
/* Fullscreen: the Panda window is a fullscreen window, completely
overlaying the entire screen and changing the desktop resolution.
Pass a valid desktop size in for win_width and win_height (win_x
and win_y are ignored). If win_width and win_height are zero,
the plugin will create a fullscreen window of its own preferred
the core API will create a fullscreen window of its own preferred
size. */
P3D_WT_fullscreen,
/* Hidden: there is no window at all for the plugin. */
/* Hidden: there is no window at all for the instance. */
P3D_WT_hidden,
} P3D_window_type;
@ -171,16 +172,16 @@ typedef enum {
/* This function pointer must be passed to P3D_new_instance(), below.
The host must pass in a pointer to a valid function in the host's
address space, or NULL. If not NULL, this function will be called
asynchronously by the plugin when the plugin needs to make a
request from the host. After this notification has been received,
the host should call P3D_instance_get_request() (at its
convenience) to retrieve the actual plugin request. If the host
passes NULL for this function pointer, asynchronous notifications
will not be provided, and the host must be responsible for calling
asynchronously by the core API when it needs to make a request from
the host. After this notification has been received, the host
should call P3D_instance_get_request() (at its convenience) to
retrieve the actual Panda request. If the host passes NULL for
this function pointer, asynchronous notifications will not be
provided, and the host must be responsible for calling
P3D_instance_get_request() from time to time. */
/* Note that, unlike the other func typedefs in this header file, this
declaration is not naming a function within the plugin itself.
declaration is not naming a function within the core API itself.
Instead, it is a typedef for a function pointer that must be
supplied by the host. */
@ -191,7 +192,8 @@ P3D_request_ready_func(P3D_instance *instance);
that appears within the embed syntax on the HTML page. An array of
these values is passed to the P3D instance to represent all of the
additional keywords that may appear within this syntax; it is up to
the plugin to interpret these additional keywords correctly. */
the Panda instance to interpret these additional keywords
correctly. */
typedef struct {
const char *_keyword;
const char *_value;
@ -202,7 +204,7 @@ typedef struct {
The user_data pointer is any arbitrary pointer value; it will be
copied into the _user_data member of the new P3D_instance object.
This pointer is intended for the host to use to store private data
associated with each instance; the plugin will not do anything with
associated with each instance; the core API will not do anything with
this data.
*/
@ -223,7 +225,7 @@ P3D_new_instance_func(P3D_request_ready_func *func, void *user_data);
correspond to the user-supplied keyword/value pairs that may appear
in the embed token within the HTML syntax; the host is responsible
for allocating this array, and for deallocating it after this call
(the plugin will make its own copy of the array).
(the core API will make its own copy of the array).
Most tokens are implemented by the application and are undefined at
the system level. However, two tokens in particular are
@ -267,7 +269,7 @@ P3D_instance_setup_window_func(P3D_instance *instance,
/********************** SCRIPTING SUPPORT **************************/
/* The following interfaces are provided to support controlling the
plugin via JavaScript or related interfaces on the browser. */
Panda instance via JavaScript or related interfaces on the browser. */
/* We require an "object" that contains some number of possible
different interfaces. An "object" might be a simple primitive like
@ -277,13 +279,13 @@ P3D_instance_setup_window_func(P3D_instance *instance,
To implement a P3D_object, we need to first define a class
definition, which is a table of methods. Most classes are defined
internally by the plugin, but the host must define at least one
internally by the core API, but the host must define at least one
class type as well, which provides callbacks into host-provided
objects.
These function types define the methods available on a class.
These are function type declarations only; they do not correspond
to named functions within the plugin DLL. Instead, the function
to named functions within the core API DLL. Instead, the function
pointers themselves are stored within the P3D_class_definition
structure, below. */
@ -297,7 +299,6 @@ typedef enum {
P3D_OT_int,
P3D_OT_float,
P3D_OT_string,
P3D_OT_list,
P3D_OT_object,
} P3D_object_type;
@ -375,33 +376,19 @@ typedef bool
P3D_object_set_property_method(P3D_object *object, const char *property,
P3D_object *value);
/* These methods are similar to the above, but for integer properties,
e.g. for elements of an array. */
typedef P3D_object *
P3D_object_get_element_method(const P3D_object *object, int n);
typedef bool
P3D_object_set_element_method(P3D_object *object, int n, P3D_object *value);
/* For objects that implement an array or list with a specific size
and all elements below that index filled in, this method will
return the size of the list. */
typedef int
P3D_object_get_list_length_method(const P3D_object *object);
/* Invokes a named method on the object. If method_name is empty or
NULL, invokes the object itself as a function. The params object
should be a list object containing the individual parameters;
ownership of this list object is transferred in this call, and it
will automatically be deleted. It may also be NULL if no
parameters are required, or a single non-list parameter if only one
parameter is required.
NULL, invokes the object itself as a function. You must pass an
array of P3D_objects as the list of parameters. The ownership of
each of the parameters in this array (but not of the array pointer
itself) is passed into this call; the objects will be deleted when
the call is completed.
The return value is a newly-allocated P3D_object on success, or
NULL on failure. Ownership of the return value is transferred to
the caller. */
typedef P3D_object *
P3D_object_call_method(const P3D_object *object, const char *method_name,
P3D_object *params);
P3D_object *params[], int num_params);
/* This defines the class structure that implements all of the above
methods. */
@ -418,9 +405,6 @@ typedef struct _P3D_class_definition {
P3D_object_get_property_method *_get_property;
P3D_object_set_property_method *_set_property;
P3D_object_get_element_method *_get_element;
P3D_object_set_element_method *_set_element;
P3D_object_get_list_length_method *_get_list_length;
P3D_object_call_method *_call;
@ -449,15 +433,11 @@ struct _P3D_object {
#define P3D_OBJECT_GET_PROPERTY(object, property) ((object)->_class->_get_property((object), (property)))
#define P3D_OBJECT_SET_PROPERTY(object, property, value) ((object)->_class->_set_property((object), (property), (value)))
#define P3D_OBJECT_GET_ELEMENT(object, n) ((object)->_class->_get_element((object), (n)))
#define P3D_OBJECT_SET_ELEMENT(object, n, value) ((object)->_class->_set_element((object), (n), (value)))
#define P3D_OBJECT_GET_LIST_LENGTH(object, n, value) ((object)->_class->_get_list_length((object), (n), (value)))
#define P3D_OBJECT_CALL(object, method_name, params) ((object)->_class->_call((object), (method_name), (params)))
#define P3D_OBJECT_CALL(object, method_name, params, num_params) ((object)->_class->_call((object), (method_name), (params), (num_params)))
/* The following function types are once again meant to define
actual function pointers to be found within the plugin DLL. */
actual function pointers to be found within the core API DLL. */
/* Returns a newly-allocated P3D_class_definition object, filled with
generic function pointers that have reasonable default behavior for
@ -492,11 +472,6 @@ P3D_new_float_object_func(double value);
typedef P3D_object *
P3D_new_string_object_func(const char *string, int length);
/* Allocates a new P3D_object of type list. The new list is empty;
use repeated calls to P3D_OBJECT_SET_ELEMENT() to populate it. */
typedef P3D_object *
P3D_new_list_object_func();
/* Returns a pointer to the top-level scriptable object of the
instance. Scripts running on the host may use this object to
communicate with the instance, by using the above methods to set or
@ -509,10 +484,10 @@ typedef P3D_object *
P3D_instance_get_script_object_func(P3D_instance *instance);
/* The inverse functionality: this supplies an object pointer to the
instance to allow the plugin to control the browser. In order to
enable browser scriptability, the host must call this method
shortly after creating the instance, preferably before calling
P3D_instance_start().
instance to allow the Panda instance to control the browser. In
order to enable browser scriptability, the host must call this
method shortly after creating the instance, preferably before
calling P3D_instance_start().
The object parameter must have been created by the host. It will
have a custom P3D_class_definition pointer, which also must have
@ -539,15 +514,15 @@ P3D_instance_set_script_object_func(P3D_instance *instance,
/********************** REQUEST HANDLING **************************/
/* The plugin may occasionally have an asynchronous request to pass up
to the host. The following structures implement this interface.
/* The core API may occasionally have an asynchronous request to pass
up to the host. The following structures implement this interface.
The design is intended to support single-threaded as well as
multi-threaded implementations in the host; there is only the one
callback function, P3D_request_ready (above), which may be called
asynchronously by the plugin. The host should be careful that this
callback function is protected from mutual access. The callback
function implementation may be as simple as setting a flag that the
host will later check within its main processing loop.
asynchronously by the core API. The host should be careful that
this callback function is protected from mutual access. The
callback function implementation may be as simple as setting a flag
that the host will later check within its main processing loop.
Once P3D_request_ready() has been received, the host should call
P3D_instance_get_request() to query the nature of the request.
@ -578,14 +553,14 @@ typedef enum {
typedef struct {
} P3D_request_stop;
/* A get_url request. The plugin would like to retrieve data for a
particular URL. The plugin is responsible for supplying a valid
/* A get_url request. The core API would like to retrieve data for a
particular URL. The core API is responsible for supplying a valid
URL string, and a unique integer ID. The unique ID is needed to
feed the results of the URL back to the plugin. If possible, the
feed the results of the URL back to the core API. If possible, the
host should be prepared to handle multiple get_url requests in
parallel, but it is allowed to handle them all one at a time if
necessary. As data comes in from the url, the host should call
P3D_instance_feed_url_stream().
P3D_instance_feed_url_stream().
*/
typedef struct {
const char *_url;
@ -626,7 +601,7 @@ typedef struct {
/* After a call to P3D_request_ready(), or from time to time in
general, the host should call this function to see if there are any
pending requests from the plugin. The function will return a
pending requests from the core API. The function will return a
freshly-allocated request if there is a request ready, or NULL if
there are no requests. After a receipt of P3D_request_ready(),
the host should call this function repeatedly until it returns NULL
@ -688,7 +663,7 @@ typedef enum {
/* This function is used by the host to handle a get_url request,
above. As it retrieves data from the URL, it should call this
function from time to time to feed that data to the plugin.
function from time to time to feed that data to the core API.
instance and unique_id are from the original get_url() request.
@ -704,9 +679,10 @@ typedef enum {
this_data and this_data_size describe the most recent block of data
retrieved from the URL. Each chunk of data passed to this function
is appended together by the plugin to define the total set of data
retrieved from the URL. For a particular call to feed_url_stream,
this may contain no data at all (e.g. this_data_size may be 0).
is appended together by the core API to define the total set of
data retrieved from the URL. For a particular call to
feed_url_stream, this may contain no data at all
(e.g. this_data_size may be 0).
The return value of this function is true if there are no problems
and the download should continue, false if there was an error
@ -739,7 +715,6 @@ EXPCL_P3D_PLUGIN P3D_new_bool_object_func P3D_new_bool_object;
EXPCL_P3D_PLUGIN P3D_new_int_object_func P3D_new_int_object;
EXPCL_P3D_PLUGIN P3D_new_float_object_func P3D_new_float_object;
EXPCL_P3D_PLUGIN P3D_new_string_object_func P3D_new_string_object;
EXPCL_P3D_PLUGIN P3D_new_list_object_func P3D_new_list_object;
EXPCL_P3D_PLUGIN P3D_instance_get_script_object_func P3D_instance_get_script_object;
EXPCL_P3D_PLUGIN P3D_instance_set_script_object_func P3D_instance_set_script_object;

View File

@ -8,7 +8,6 @@
#include "p3dInstance.cxx"
#include "p3dInstanceManager.cxx"
#include "p3dIntObject.cxx"
#include "p3dListObject.cxx"
#include "p3dMultifileReader.cxx"
#include "p3dPythonObject.cxx"
#include "p3dNoneObject.cxx"

View File

@ -301,7 +301,6 @@ object_to_variant(NPVariant *result, const P3D_object *object) {
}
break;
case P3D_OT_list:
case P3D_OT_object:
{
PPPandaObject *ppobj = PPPandaObject::make_new(_instance, P3D_OBJECT_COPY(object));