P3D_object needs to be reference-counted
This commit is contained in:
parent
e214d8c9ef
commit
fbf81f90eb
|
|
@ -41,7 +41,7 @@ P3DBoolObject(const P3DBoolObject ©) :
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DBoolObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_bool;
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DBoolObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ get_bool() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DBoolObject::
|
||||
get_int() const {
|
||||
get_int() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ get_int() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DBoolObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
if (_value) {
|
||||
value = "True";
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ public:
|
|||
P3DBoolObject(const P3DBoolObject ©);
|
||||
|
||||
public:
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual int get_int() const;
|
||||
virtual void make_string(string &value) const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual int get_int();
|
||||
virtual void make_string(string &value);
|
||||
|
||||
private:
|
||||
bool _value;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ P3DFloatObject(const P3DFloatObject ©) :
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DFloatObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_float;
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DFloatObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
return (_value != 0.0);
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ get_bool() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DFloatObject::
|
||||
get_int() const {
|
||||
get_int() {
|
||||
return (int)_value;
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ get_int() const {
|
|||
// value, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double P3DFloatObject::
|
||||
get_float() const {
|
||||
get_float() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ get_float() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DFloatObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
ostringstream strm;
|
||||
strm << _value;
|
||||
value = strm.str();
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ public:
|
|||
P3DFloatObject(const P3DFloatObject ©);
|
||||
|
||||
public:
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual int get_int() const;
|
||||
virtual double get_float() const;
|
||||
virtual void make_string(string &value) const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual int get_int();
|
||||
virtual double get_float();
|
||||
virtual void make_string(string &value);
|
||||
|
||||
private:
|
||||
double _value;
|
||||
|
|
|
|||
|
|
@ -73,9 +73,7 @@ P3DInstance::
|
|||
~P3DInstance() {
|
||||
assert(_session == NULL);
|
||||
|
||||
if (_browser_script_object != NULL) {
|
||||
P3D_OBJECT_FINISH(_browser_script_object);
|
||||
}
|
||||
P3D_OBJECT_XDECREF(_browser_script_object);
|
||||
|
||||
DESTROY_LOCK(_request_lock);
|
||||
|
||||
|
|
@ -118,6 +116,7 @@ set_fparams(const P3DFileParams &fparams) {
|
|||
strm << inst_mgr->get_unique_session_index();
|
||||
_session_key = strm.str();
|
||||
|
||||
// TODO.
|
||||
_python_version = "python24";
|
||||
|
||||
|
||||
|
|
@ -200,7 +199,8 @@ get_panda_script_object() const {
|
|||
}
|
||||
|
||||
if (result == NULL) {
|
||||
result = new P3DUndefinedObject;
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
result = inst_mgr->new_undefined_object();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -211,16 +211,18 @@ get_panda_script_object() const {
|
|||
// Access: Public
|
||||
// Description: Stores a pointer to the top-level window object
|
||||
// of the browser, to be used by Panda code to control
|
||||
// JavaScript. Ownership of this object is passed into
|
||||
// the instance.
|
||||
// JavaScript. The new object's reference count is
|
||||
// incremented, and the previous object's is
|
||||
// decremented.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
set_browser_script_object(P3D_object *browser_script_object) {
|
||||
if (browser_script_object != _browser_script_object) {
|
||||
if (_browser_script_object != NULL) {
|
||||
P3D_OBJECT_FINISH(_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 (_session != NULL) {
|
||||
send_browser_script_object();
|
||||
|
|
@ -317,6 +319,36 @@ void P3DInstance::
|
|||
finish_request(P3D_request *request, bool handled) {
|
||||
assert(request != NULL);
|
||||
|
||||
switch (request->_request_type) {
|
||||
case P3D_RT_stop:
|
||||
break;
|
||||
|
||||
case P3D_RT_get_url:
|
||||
free((char *)request->_request._get_url._url);
|
||||
break;
|
||||
|
||||
case P3D_RT_post_url:
|
||||
free((char *)request->_request._post_url._url);
|
||||
free((char *)request->_request._post_url._post_data);
|
||||
break;
|
||||
|
||||
case P3D_RT_notify:
|
||||
free((char *)request->_request._notify._message);
|
||||
break;
|
||||
|
||||
case P3D_RT_script:
|
||||
{
|
||||
P3D_OBJECT_DECREF(request->_request._script._object);
|
||||
if (request->_request._script._property_name != NULL) {
|
||||
free((char *)request->_request._script._property_name);
|
||||
}
|
||||
for (int i = 0; i < request->_request._script._num_values; ++i) {
|
||||
P3D_OBJECT_DECREF(request->_request._script._values[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
delete request;
|
||||
}
|
||||
|
||||
|
|
@ -519,7 +551,7 @@ handle_script_request(P3D_request *request) {
|
|||
doc->LinkEndChild(xcommand);
|
||||
if (result != NULL) {
|
||||
xcommand->LinkEndChild(_session->p3dobj_to_xml(result));
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
if (needs_response) {
|
||||
|
|
@ -598,10 +630,6 @@ handle_script_request(P3D_request *request) {
|
|||
P3D_OBJECT_CALL(object, request->_request._script._property_name,
|
||||
request->_request._script._values,
|
||||
request->_request._script._num_values);
|
||||
// Reset the value count to 0 so we won't double-delete the
|
||||
// parameter values when the request is deleted (the above call
|
||||
// has already deleted them).
|
||||
request->_request._script._num_values = 0;
|
||||
|
||||
// Feed the result back down to the subprocess.
|
||||
TiXmlDocument *doc = new TiXmlDocument;
|
||||
|
|
@ -615,7 +643,7 @@ handle_script_request(P3D_request *request) {
|
|||
|
||||
if (result != NULL) {
|
||||
xcommand->LinkEndChild(_session->p3dobj_to_xml(result));
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
if (needs_response) {
|
||||
|
|
@ -654,7 +682,7 @@ handle_script_request(P3D_request *request) {
|
|||
|
||||
if (result != NULL) {
|
||||
xcommand->LinkEndChild(_session->p3dobj_to_xml(result));
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
logfile << "eval response: " << *doc << "\n";
|
||||
|
|
|
|||
|
|
@ -70,3 +70,40 @@ inline int P3DInstanceManager::
|
|||
get_num_instances() const {
|
||||
return _instances.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::new_undefined_object
|
||||
// Access: Public
|
||||
// Description: Returns the singleton "undefined" object, as a new
|
||||
// reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline P3D_object *P3DInstanceManager::
|
||||
new_undefined_object() {
|
||||
P3D_OBJECT_INCREF(_undefined_object);
|
||||
return _undefined_object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::new_none_object
|
||||
// Access: Public
|
||||
// Description: Returns the singleton "none" object, as a new
|
||||
// reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline P3D_object *P3DInstanceManager::
|
||||
new_none_object() {
|
||||
P3D_OBJECT_INCREF(_none_object);
|
||||
return _none_object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstanceManager::new_bool_object
|
||||
// Access: Public
|
||||
// Description: Returns the singleton "true" or "false" object, as a
|
||||
// new reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline P3D_object *P3DInstanceManager::
|
||||
new_bool_object(bool value) {
|
||||
P3D_object *obj = (value) ? _true_object : _false_object;
|
||||
P3D_OBJECT_INCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
#include "p3dPackage.h"
|
||||
#include "p3d_plugin_config.h"
|
||||
#include "p3dWinSplashWindow.h"
|
||||
#include "p3dUndefinedObject.h"
|
||||
#include "p3dNoneObject.h"
|
||||
#include "p3dBoolObject.h"
|
||||
#include "find_root_dir.h"
|
||||
#include "mkdir_complete.h"
|
||||
|
||||
|
|
@ -43,6 +46,12 @@ P3DInstanceManager() {
|
|||
_started_notify_thread = false;
|
||||
INIT_THREAD(_notify_thread);
|
||||
|
||||
// Initialize the singleton objects.
|
||||
_undefined_object = new P3DUndefinedObject();
|
||||
_none_object = new P3DNoneObject();
|
||||
_true_object = new P3DBoolObject(true);
|
||||
_false_object = new P3DBoolObject(false);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Ensure the appropriate Windows common controls are available to
|
||||
// this application.
|
||||
|
|
@ -72,6 +81,22 @@ P3DInstanceManager::
|
|||
assert(_instances.empty());
|
||||
assert(_sessions.empty());
|
||||
|
||||
nout << "counts: " << _undefined_object->_ref_count
|
||||
<< " " << _none_object->_ref_count
|
||||
<< " " << _true_object->_ref_count
|
||||
<< " " << _false_object->_ref_count
|
||||
<< "\n" << flush;
|
||||
|
||||
assert(_undefined_object->_ref_count == 1);
|
||||
assert(_none_object->_ref_count == 1);
|
||||
assert(_true_object->_ref_count == 1);
|
||||
assert(_false_object->_ref_count == 1);
|
||||
|
||||
P3D_OBJECT_DECREF(_undefined_object);
|
||||
P3D_OBJECT_DECREF(_none_object);
|
||||
P3D_OBJECT_DECREF(_true_object);
|
||||
P3D_OBJECT_DECREF(_false_object);
|
||||
|
||||
#ifdef _WIN32
|
||||
P3DWinSplashWindow::unregister_window_class();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ public:
|
|||
|
||||
P3D_class_definition *make_class_definition() const;
|
||||
|
||||
inline P3D_object *new_undefined_object();
|
||||
inline P3D_object *new_none_object();
|
||||
inline P3D_object *new_bool_object(bool value);
|
||||
|
||||
static P3DInstanceManager *get_global_ptr();
|
||||
static void delete_global_ptr();
|
||||
|
||||
|
|
@ -82,6 +86,11 @@ private:
|
|||
string _download_url;
|
||||
string _platform;
|
||||
|
||||
P3D_object *_undefined_object;
|
||||
P3D_object *_none_object;
|
||||
P3D_object *_true_object;
|
||||
P3D_object *_false_object;
|
||||
|
||||
typedef set<P3DInstance *> Instances;
|
||||
Instances _instances;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ P3DIntObject(const P3DIntObject ©) :
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DIntObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_int;
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DIntObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
return (_value != 0);
|
||||
}
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ get_bool() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DIntObject::
|
||||
get_int() const {
|
||||
get_int() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ get_int() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DIntObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
ostringstream strm;
|
||||
strm << _value;
|
||||
value = strm.str();
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ public:
|
|||
P3DIntObject(const P3DIntObject ©);
|
||||
|
||||
public:
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual int get_int() const;
|
||||
virtual void make_string(string &value) const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual int get_int();
|
||||
virtual void make_string(string &value);
|
||||
|
||||
private:
|
||||
int _value;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ P3DNoneObject() {
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DNoneObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_none;
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DNoneObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +51,6 @@ get_bool() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DNoneObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
value = "None";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ public:
|
|||
P3DNoneObject();
|
||||
|
||||
public:
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual void make_string(string &value) const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual void make_string(string &value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -37,39 +37,3 @@ P3DObject(const P3DObject ©) {
|
|||
_class = copy._class;
|
||||
_ref_count = 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DObject::ref
|
||||
// Access: Public
|
||||
// Description: Increments the reference count.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void P3DObject::
|
||||
ref() const {
|
||||
++(((P3DObject *)this)->_ref_count);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DObject::unref
|
||||
// Access: Public
|
||||
// Description: Decrements the reference count, and returns the new
|
||||
// count.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline int P3DObject::
|
||||
unref() const {
|
||||
--(((P3DObject *)this)->_ref_count);
|
||||
return _ref_count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DObject::unref_delete
|
||||
// Access: Public, Static
|
||||
// Description: Decrements the reference count on the indicated
|
||||
// object, and deletes it if the reference count reaches
|
||||
// zero.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void P3DObject::
|
||||
unref_delete(P3DObject *obj) {
|
||||
if (obj->unref() <= 0) {
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,47 +21,42 @@
|
|||
// P3D_object structure.
|
||||
static void
|
||||
object_finish(P3D_object *object) {
|
||||
P3DObject::unref_delete(((P3DObject *)object));
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
object_copy(const P3D_object *object) {
|
||||
return ((const P3DObject *)object)->make_copy();
|
||||
delete (P3DObject *)object;
|
||||
}
|
||||
|
||||
static P3D_object_type
|
||||
object_get_type(const P3D_object *object) {
|
||||
return ((const P3DObject *)object)->get_type();
|
||||
object_get_type(P3D_object *object) {
|
||||
return ((P3DObject *)object)->get_type();
|
||||
}
|
||||
|
||||
static bool
|
||||
object_get_bool(const P3D_object *object) {
|
||||
return ((const P3DObject *)object)->get_bool();
|
||||
object_get_bool(P3D_object *object) {
|
||||
return ((P3DObject *)object)->get_bool();
|
||||
}
|
||||
|
||||
static int
|
||||
object_get_int(const P3D_object *object) {
|
||||
return ((const P3DObject *)object)->get_int();
|
||||
object_get_int(P3D_object *object) {
|
||||
return ((P3DObject *)object)->get_int();
|
||||
}
|
||||
|
||||
static double
|
||||
object_get_float(const P3D_object *object) {
|
||||
return ((const P3DObject *)object)->get_float();
|
||||
object_get_float(P3D_object *object) {
|
||||
return ((P3DObject *)object)->get_float();
|
||||
}
|
||||
|
||||
static int
|
||||
object_get_string(const P3D_object *object, char *buffer, int buffer_length) {
|
||||
return ((const P3DObject *)object)->get_string(buffer, buffer_length);
|
||||
object_get_string(P3D_object *object, char *buffer, int buffer_length) {
|
||||
return ((P3DObject *)object)->get_string(buffer, buffer_length);
|
||||
}
|
||||
|
||||
static int
|
||||
object_get_repr(const P3D_object *object, char *buffer, int buffer_length) {
|
||||
return ((const P3DObject *)object)->get_repr(buffer, buffer_length);
|
||||
object_get_repr(P3D_object *object, char *buffer, int buffer_length) {
|
||||
return ((P3DObject *)object)->get_repr(buffer, buffer_length);
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
object_get_property(const P3D_object *object, const char *property) {
|
||||
return ((const P3DObject *)object)->get_property(property);
|
||||
object_get_property(P3D_object *object, const char *property) {
|
||||
return ((P3DObject *)object)->get_property(property);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -71,27 +66,26 @@ object_set_property(P3D_object *object, const char *property,
|
|||
}
|
||||
|
||||
static bool
|
||||
object_has_method(const P3D_object *object, const char *method_name) {
|
||||
return ((const P3DObject *)object)->has_method(method_name);
|
||||
object_has_method(P3D_object *object, const char *method_name) {
|
||||
return ((P3DObject *)object)->has_method(method_name);
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
object_call(const P3D_object *object, const char *method_name,
|
||||
object_call(P3D_object *object, const char *method_name,
|
||||
P3D_object *params[], int num_params) {
|
||||
if (method_name == NULL) {
|
||||
method_name = "";
|
||||
}
|
||||
return ((const P3DObject *)object)->call(method_name, params, num_params);
|
||||
return ((P3DObject *)object)->call(method_name, params, num_params);
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
object_eval(const P3D_object *object, const char *expression) {
|
||||
return ((const P3DObject *)object)->eval(expression);
|
||||
object_eval(P3D_object *object, const char *expression) {
|
||||
return ((P3DObject *)object)->eval(expression);
|
||||
}
|
||||
|
||||
P3D_class_definition P3DObject::_object_class = {
|
||||
&object_finish,
|
||||
&object_copy,
|
||||
&object_get_type,
|
||||
&object_get_bool,
|
||||
&object_get_int,
|
||||
|
|
@ -116,14 +110,8 @@ generic_finish(P3D_object *object) {
|
|||
nout << "Warning! default object_finish() method does nothing; object will leak.\n" << flush;
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
generic_copy(const P3D_object *object) {
|
||||
nout << "Warning! default object_copy() method does nothing; object pointer will be shared.\n" << flush;
|
||||
return (P3D_object *)object;
|
||||
}
|
||||
|
||||
static P3D_object_type
|
||||
generic_get_type(const P3D_object *object) {
|
||||
generic_get_type(P3D_object *object) {
|
||||
// We assume anyone going through the trouble of subclassing this
|
||||
// will want to return an object, not one of the other fundamental
|
||||
// types.
|
||||
|
|
@ -131,66 +119,59 @@ generic_get_type(const P3D_object *object) {
|
|||
}
|
||||
|
||||
static bool
|
||||
generic_get_bool(const P3D_object *object) {
|
||||
generic_get_bool(P3D_object *object) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
generic_get_int(const P3D_object *object) {
|
||||
generic_get_int(P3D_object *object) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double
|
||||
generic_get_float(const P3D_object *object) {
|
||||
generic_get_float(P3D_object *object) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
static int
|
||||
generic_get_string(const P3D_object *object, char *buffer, int buffer_length) {
|
||||
generic_get_string(P3D_object *object, char *buffer, int buffer_length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
generic_get_repr(const P3D_object *object, char *buffer, int buffer_length) {
|
||||
generic_get_repr(P3D_object *object, char *buffer, int buffer_length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
generic_get_property(const P3D_object *object, const char *property) {
|
||||
generic_get_property(P3D_object *object, const char *property) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
generic_set_property(P3D_object *object, const char *property,
|
||||
P3D_object *value) {
|
||||
if (value != NULL) {
|
||||
P3D_OBJECT_FINISH(value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
generic_has_method(const P3D_object *object, const char *method_name) {
|
||||
return ((const P3DObject *)object)->has_method(method_name);
|
||||
generic_has_method(P3D_object *object, const char *method_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
generic_call(const P3D_object *object, const char *method_name,
|
||||
generic_call(P3D_object *object, const char *method_name,
|
||||
P3D_object *params[], int num_params) {
|
||||
for (int i = 0; i < num_params; ++i) {
|
||||
P3D_OBJECT_FINISH(params[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
generic_eval(const P3D_object *object, const char *expression) {
|
||||
generic_eval(P3D_object *object, const char *expression) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
P3D_class_definition P3DObject::_generic_class = {
|
||||
&generic_finish,
|
||||
&generic_copy,
|
||||
&generic_get_type,
|
||||
&generic_get_bool,
|
||||
&generic_get_int,
|
||||
|
|
@ -211,20 +192,7 @@ P3D_class_definition P3DObject::_generic_class = {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
P3DObject::
|
||||
~P3DObject() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DObject::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 *P3DObject::
|
||||
make_copy() const {
|
||||
ref();
|
||||
return (P3DObject *)this;
|
||||
assert(_ref_count == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -234,7 +202,7 @@ make_copy() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DObject::
|
||||
get_int() const {
|
||||
get_int() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +213,7 @@ get_int() const {
|
|||
// value, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double P3DObject::
|
||||
get_float() const {
|
||||
get_float() {
|
||||
return get_int();
|
||||
}
|
||||
|
||||
|
|
@ -260,7 +228,7 @@ get_float() const {
|
|||
// was too small).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DObject::
|
||||
get_string(char *buffer, int buffer_length) const {
|
||||
get_string(char *buffer, int buffer_length) {
|
||||
string result;
|
||||
make_string(result);
|
||||
strncpy(buffer, result.c_str(), buffer_length);
|
||||
|
|
@ -274,7 +242,7 @@ get_string(char *buffer, int buffer_length) const {
|
|||
// similar to get_string(), above.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DObject::
|
||||
get_repr(char *buffer, int buffer_length) const {
|
||||
get_repr(char *buffer, int buffer_length) {
|
||||
ostringstream strm;
|
||||
output(strm);
|
||||
string result = strm.str();
|
||||
|
|
@ -290,7 +258,7 @@ get_repr(char *buffer, int buffer_length) const {
|
|||
// that must be deleted by the caller, or NULL on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DObject::
|
||||
get_property(const string &property) const {
|
||||
get_property(const string &property) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -303,9 +271,6 @@ get_property(const string &property) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DObject::
|
||||
set_property(const string &property, P3D_object *value) {
|
||||
if (value != NULL) {
|
||||
P3D_OBJECT_FINISH(value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +281,7 @@ set_property(const string &property, P3D_object *value) {
|
|||
// object, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DObject::
|
||||
has_method(const string &method_name) const {
|
||||
has_method(const string &method_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -329,10 +294,7 @@ has_method(const string &method_name) const {
|
|||
// on success, NULL on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DObject::
|
||||
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]);
|
||||
}
|
||||
call(const string &method_name, P3D_object *params[], int num_params) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -343,7 +305,7 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
|
|||
// of the P3DObject classes implement this.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DObject::
|
||||
eval(const string &expression) const {
|
||||
eval(const string &expression) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -355,7 +317,7 @@ eval(const string &expression) const {
|
|||
// assistance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DObject::
|
||||
output(ostream &out) const {
|
||||
output(ostream &out) {
|
||||
string value;
|
||||
make_string(value);
|
||||
out << value;
|
||||
|
|
|
|||
|
|
@ -33,32 +33,24 @@ protected:
|
|||
public:
|
||||
virtual ~P3DObject();
|
||||
|
||||
virtual P3DObject *make_copy() const;
|
||||
virtual P3D_object_type get_type() const=0;
|
||||
virtual bool get_bool() const=0;
|
||||
virtual int get_int() const;
|
||||
virtual double get_float() const;
|
||||
virtual P3D_object_type get_type()=0;
|
||||
virtual bool get_bool()=0;
|
||||
virtual int get_int();
|
||||
virtual double get_float();
|
||||
|
||||
int get_string(char *buffer, int buffer_length) const;
|
||||
int get_repr(char *buffer, int buffer_length) const;
|
||||
virtual void make_string(string &value) const=0;
|
||||
int get_string(char *buffer, int buffer_length);
|
||||
int get_repr(char *buffer, int buffer_length);
|
||||
virtual void make_string(string &value)=0;
|
||||
|
||||
virtual P3D_object *get_property(const string &property) const;
|
||||
virtual P3D_object *get_property(const string &property);
|
||||
virtual bool set_property(const string &property, P3D_object *value);
|
||||
|
||||
virtual bool has_method(const string &method_name) const;
|
||||
virtual bool has_method(const string &method_name);
|
||||
virtual P3D_object *call(const string &method_name,
|
||||
P3D_object *params[], int num_params) const;
|
||||
virtual P3D_object *eval(const string &expression) const;
|
||||
P3D_object *params[], int num_params);
|
||||
virtual P3D_object *eval(const string &expression);
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
inline void ref() const;
|
||||
inline int unref() const;
|
||||
static inline void unref_delete(P3DObject *obj);
|
||||
|
||||
private:
|
||||
int _ref_count;
|
||||
virtual void output(ostream &out);
|
||||
|
||||
public:
|
||||
static P3D_class_definition _object_class;
|
||||
|
|
@ -71,7 +63,7 @@ public:
|
|||
// virtual method to write the output simply. (For classes that
|
||||
// inherit only from P3D_object, we have to use the generic C method
|
||||
// defined in p3d_plugin_common.h, a little clumsier.)
|
||||
inline ostream &operator << (ostream &out, const P3DObject &value) {
|
||||
inline ostream &operator << (ostream &out, P3DObject &value) {
|
||||
value.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ P3DPythonObject::
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DPythonObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_object;
|
||||
}
|
||||
|
||||
|
|
@ -53,13 +53,13 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DPythonObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
bool bresult = 0;
|
||||
|
||||
P3D_object *result = call("__bool__", NULL, 0);
|
||||
if (result != NULL) {
|
||||
bresult = P3D_OBJECT_GET_BOOL(result);
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
return bresult;
|
||||
|
|
@ -72,13 +72,13 @@ get_bool() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DPythonObject::
|
||||
get_int() const {
|
||||
get_int() {
|
||||
int iresult = 0;
|
||||
|
||||
P3D_object *result = call("__int__", NULL, 0);
|
||||
if (result != NULL) {
|
||||
iresult = P3D_OBJECT_GET_INT(result);
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
return iresult;
|
||||
|
|
@ -91,13 +91,13 @@ get_int() const {
|
|||
// value, if possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double P3DPythonObject::
|
||||
get_float() const {
|
||||
get_float() {
|
||||
double fresult = 0.0;
|
||||
|
||||
P3D_object *result = call("__float__", NULL, 0);
|
||||
if (result != NULL) {
|
||||
fresult = P3D_OBJECT_GET_FLOAT(result);
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
return fresult;
|
||||
|
|
@ -110,7 +110,7 @@ get_float() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPythonObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
P3D_object *result = call("__str__", NULL, 0);
|
||||
if (result != NULL) {
|
||||
int size = P3D_OBJECT_GET_STRING(result, NULL, 0);
|
||||
|
|
@ -119,7 +119,7 @@ make_string(string &value) const {
|
|||
value = string(buffer, size);
|
||||
delete[] buffer;
|
||||
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ make_string(string &value) const {
|
|||
// that must be deleted by the caller, or NULL on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DPythonObject::
|
||||
get_property(const string &property) const {
|
||||
get_property(const string &property) {
|
||||
P3D_object *params[1];
|
||||
params[0] = new P3DStringObject(property);
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ set_property(const string &property, P3D_object *value) {
|
|||
|
||||
if (result != NULL) {
|
||||
bresult = P3D_OBJECT_GET_BOOL(result);
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
return bresult;
|
||||
|
|
@ -180,7 +180,7 @@ set_property(const string &property, P3D_object *value) {
|
|||
// object, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DPythonObject::
|
||||
has_method(const string &method_name) const {
|
||||
has_method(const string &method_name) {
|
||||
bool bresult = false;
|
||||
|
||||
P3D_object *params[1];
|
||||
|
|
@ -190,7 +190,7 @@ has_method(const string &method_name) const {
|
|||
|
||||
if (result != NULL) {
|
||||
bresult = P3D_OBJECT_GET_BOOL(result);
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
|
||||
return bresult;
|
||||
|
|
@ -205,7 +205,7 @@ has_method(const string &method_name) const {
|
|||
// on success, NULL on error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DPythonObject::
|
||||
call(const string &method_name, P3D_object *params[], int num_params) const {
|
||||
call(const string &method_name, P3D_object *params[], int num_params) {
|
||||
TiXmlDocument *doc = new TiXmlDocument;
|
||||
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
|
||||
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||
|
|
@ -222,10 +222,6 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
|
|||
for (int i = 0; i < num_params; ++i) {
|
||||
TiXmlElement *xparams = _session->p3dobj_to_xml(params[i]);
|
||||
xcommand->LinkEndChild(xparams);
|
||||
|
||||
// Now we're done with the params object passed in, we can delete
|
||||
// it as promised.
|
||||
P3D_OBJECT_FINISH(params[i]);
|
||||
}
|
||||
|
||||
doc->LinkEndChild(decl);
|
||||
|
|
@ -255,12 +251,12 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
|
|||
// assistance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPythonObject::
|
||||
output(ostream &out) const {
|
||||
output(ostream &out) {
|
||||
P3D_object *result = call("__repr__", NULL, 0);
|
||||
out << "Python " << _object_id;
|
||||
if (result != NULL) {
|
||||
out << ": " << *result;
|
||||
P3D_OBJECT_FINISH(result);
|
||||
P3D_OBJECT_DECREF(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +267,7 @@ output(ostream &out) const {
|
|||
// identify this object in the XML stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int P3DPythonObject::
|
||||
get_object_id() const {
|
||||
get_object_id() {
|
||||
return _object_id;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,22 +34,22 @@ public:
|
|||
virtual ~P3DPythonObject();
|
||||
|
||||
public:
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual int get_int() const;
|
||||
virtual double get_float() const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual int get_int();
|
||||
virtual double get_float();
|
||||
|
||||
virtual void make_string(string &value) const;
|
||||
virtual void make_string(string &value);
|
||||
|
||||
virtual P3D_object *get_property(const string &property) const;
|
||||
virtual P3D_object *get_property(const string &property);
|
||||
virtual bool set_property(const string &property, P3D_object *value);
|
||||
|
||||
virtual bool has_method(const string &method_name) const;
|
||||
virtual bool has_method(const string &method_name);
|
||||
virtual P3D_object *call(const string &method_name,
|
||||
P3D_object *params[], int num_params) const;
|
||||
P3D_object *params[], int num_params);
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
int get_object_id() const;
|
||||
virtual void output(ostream &out);
|
||||
int get_object_id();
|
||||
|
||||
private:
|
||||
P3DSession *_session;
|
||||
|
|
|
|||
|
|
@ -321,21 +321,23 @@ command_and_response(TiXmlDocument *command) {
|
|||
// Access: Public
|
||||
// Description: Converts the XML representation of the particular
|
||||
// object value into a corresponding P3D_object.
|
||||
// Returns the newly-allocated object.
|
||||
// Returns the object, a new reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object *P3DSession::
|
||||
xml_to_p3dobj(const TiXmlElement *xvalue) {
|
||||
const char *type = xvalue->Attribute("type");
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
if (strcmp(type, "undefined") == 0) {
|
||||
return new P3DUndefinedObject;
|
||||
return inst_mgr->new_undefined_object();
|
||||
|
||||
} else if (strcmp(type, "none") == 0) {
|
||||
return new P3DNoneObject;
|
||||
return inst_mgr->new_none_object();
|
||||
|
||||
} else if (strcmp(type, "bool") == 0) {
|
||||
int value;
|
||||
if (xvalue->QueryIntAttribute("value", &value) == TIXML_SUCCESS) {
|
||||
return new P3DBoolObject(value != 0);
|
||||
return inst_mgr->new_bool_object(value != 0);
|
||||
}
|
||||
|
||||
} else if (strcmp(type, "int") == 0) {
|
||||
|
|
@ -364,11 +366,12 @@ xml_to_p3dobj(const TiXmlElement *xvalue) {
|
|||
SentObjects::iterator si = _sent_objects.find(object_id);
|
||||
if (si == _sent_objects.end()) {
|
||||
// Hmm, the child process gave us a bogus object ID.
|
||||
return new P3DUndefinedObject;
|
||||
return inst_mgr->new_undefined_object();
|
||||
}
|
||||
|
||||
P3D_object *obj = (*si).second;
|
||||
return P3D_OBJECT_COPY(obj);
|
||||
P3D_OBJECT_INCREF(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
} else if (strcmp(type, "python") == 0) {
|
||||
|
|
@ -379,7 +382,7 @@ xml_to_p3dobj(const TiXmlElement *xvalue) {
|
|||
}
|
||||
|
||||
// Something went wrong in decoding.
|
||||
return new P3DUndefinedObject;
|
||||
return inst_mgr->new_undefined_object();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -387,10 +390,11 @@ xml_to_p3dobj(const TiXmlElement *xvalue) {
|
|||
// Access: Public
|
||||
// Description: Allocates and returns a new XML structure
|
||||
// corresponding to the indicated value. The supplied
|
||||
// P3DObject passed in is *not* deleted.
|
||||
// P3DObject's reference count is not decremented; the
|
||||
// caller remains responsible for decrementing it later.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TiXmlElement *P3DSession::
|
||||
p3dobj_to_xml(const P3D_object *obj) {
|
||||
p3dobj_to_xml(P3D_object *obj) {
|
||||
TiXmlElement *xvalue = new TiXmlElement("value");
|
||||
|
||||
switch (P3D_OBJECT_GET_TYPE(obj)) {
|
||||
|
|
@ -443,21 +447,21 @@ p3dobj_to_xml(const P3D_object *obj) {
|
|||
// should pass a reference down to this particular object, so
|
||||
// the Python process knows to call back up to here to query it.
|
||||
|
||||
P3D_object *dup = P3D_OBJECT_COPY(obj);
|
||||
|
||||
int object_id = _next_sent_id;
|
||||
++_next_sent_id;
|
||||
bool inserted = _sent_objects.insert(SentObjects::value_type(object_id, dup)).second;
|
||||
bool inserted = _sent_objects.insert(SentObjects::value_type(object_id, obj)).second;
|
||||
while (!inserted) {
|
||||
// Hmm, we must have cycled around the entire int space? Either
|
||||
// that, or there's a logic bug somewhere. Assume the former,
|
||||
// and keep looking for an empty slot.
|
||||
object_id = _next_sent_id;
|
||||
++_next_sent_id;
|
||||
inserted = _sent_objects.insert(SentObjects::value_type(object_id, dup)).second;
|
||||
inserted = _sent_objects.insert(SentObjects::value_type(object_id, obj)).second;
|
||||
}
|
||||
|
||||
// Now that it's stored in the map, increment its reference count.
|
||||
// TODO: implement removing things from this map.
|
||||
P3D_OBJECT_INCREF(obj);
|
||||
|
||||
xvalue->SetAttribute("type", "browser");
|
||||
xvalue->SetAttribute("object_id", object_id);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
void send_command(TiXmlDocument *command);
|
||||
TiXmlDocument *command_and_response(TiXmlDocument *command);
|
||||
P3D_object *xml_to_p3dobj(const TiXmlElement *xvalue);
|
||||
TiXmlElement *p3dobj_to_xml(const P3D_object *obj);
|
||||
TiXmlElement *p3dobj_to_xml(P3D_object *obj);
|
||||
|
||||
private:
|
||||
void install_progress(P3DPackage *package, double progress);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ P3DStringObject::
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DStringObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_string;
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DStringObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
return !_value.empty();
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ get_bool() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DStringObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
value = _value;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ make_string(string &value) const {
|
|||
// assistance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DStringObject::
|
||||
output(ostream &out) const {
|
||||
output(ostream &out) {
|
||||
out << '"';
|
||||
for (string::const_iterator si = _value.begin(); si != _value.end(); ++si) {
|
||||
if (isprint(*si)) {
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ public:
|
|||
public:
|
||||
virtual ~P3DStringObject();
|
||||
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual void make_string(string &value) const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual void make_string(string &value);
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void output(ostream &out);
|
||||
|
||||
private:
|
||||
string _value;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ P3DUndefinedObject() {
|
|||
// Description: Returns the fundamental type of this kind of object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_object_type P3DUndefinedObject::
|
||||
get_type() const {
|
||||
get_type() {
|
||||
return P3D_OT_undefined;
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ get_type() const {
|
|||
// possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool P3DUndefinedObject::
|
||||
get_bool() const {
|
||||
get_bool() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +51,6 @@ get_bool() const {
|
|||
// of this object coerced to a string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DUndefinedObject::
|
||||
make_string(string &value) const {
|
||||
make_string(string &value) {
|
||||
value = "Undefined";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ public:
|
|||
P3DUndefinedObject();
|
||||
|
||||
public:
|
||||
virtual P3D_object_type get_type() const;
|
||||
virtual bool get_bool() const;
|
||||
virtual void make_string(string &value) const;
|
||||
virtual P3D_object_type get_type();
|
||||
virtual bool get_bool();
|
||||
virtual void make_string(string &value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ P3D_new_undefined_object() {
|
|||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
|
||||
P3D_object *result = new P3DUndefinedObject();
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
P3D_object *result = inst_mgr->new_undefined_object();
|
||||
|
||||
RELEASE_LOCK(_api_lock);
|
||||
return result;
|
||||
|
|
@ -149,7 +150,8 @@ P3D_new_none_object() {
|
|||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
|
||||
P3D_object *result = new P3DNoneObject();
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
P3D_object *result = inst_mgr->new_none_object();
|
||||
|
||||
RELEASE_LOCK(_api_lock);
|
||||
return result;
|
||||
|
|
@ -160,7 +162,8 @@ P3D_new_bool_object(bool value) {
|
|||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
|
||||
P3D_object *result = new P3DBoolObject(value);
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
P3D_object *result = inst_mgr->new_bool_object(value);
|
||||
|
||||
RELEASE_LOCK(_api_lock);
|
||||
return result;
|
||||
|
|
@ -212,7 +215,7 @@ P3D_instance_get_panda_script_object(P3D_instance *instance) {
|
|||
|
||||
void
|
||||
P3D_instance_set_browser_script_object(P3D_instance *instance,
|
||||
P3D_object *object) {
|
||||
P3D_object *object) {
|
||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||
ACQUIRE_LOCK(_api_lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -307,25 +307,30 @@ typedef enum {
|
|||
P3D_OT_object,
|
||||
} P3D_object_type;
|
||||
|
||||
/* Most methods and functions that return a P3D_object return it with
|
||||
its reference count already incremented by one for the benefit of
|
||||
the caller, leaving the caller the owner of the implicit reference
|
||||
count. This is referred to as returning a "new reference", using
|
||||
the Python naming convention. Similarly, most methods that receive
|
||||
a P3D_object will implicitly increment the reference count
|
||||
internally if necessary, leaving the caller still the owner of its
|
||||
own reference count. Thus, it is the caller's responsibility to
|
||||
call P3D_OBJECT_DECREF() on any P3D_objects it has received but no
|
||||
longer wishes to keep. */
|
||||
|
||||
/* This method is called to deallocate the object and all of its
|
||||
internal structures. */
|
||||
internal structures. Do not call it directly; call
|
||||
P3D_OBJECT_DECREF() instead. */
|
||||
typedef void
|
||||
P3D_object_finish_method(P3D_object *object);
|
||||
|
||||
/* Returns a new copy of the object. The caller receives ownership of
|
||||
the new object and must eventually pass its pointer to
|
||||
P3D_OBJECT_FINISH() to delete it, or into some other call that
|
||||
transfers ownership. */
|
||||
typedef P3D_object *
|
||||
P3D_object_copy_method(const P3D_object *object);
|
||||
|
||||
/* Returns the fundamental type of the object. This should be treated
|
||||
as a hint to suggest how the object can most accurately be
|
||||
represented; it does not limit the actual interfaces available to
|
||||
an object. For instance, you may call P3D_OBJECT_GET_PROPERTY()
|
||||
even if the object's type is not "object". */
|
||||
typedef P3D_object_type
|
||||
P3D_object_get_type_method(const P3D_object *object);
|
||||
P3D_object_get_type_method(P3D_object *object);
|
||||
|
||||
/* Each of the following methods returns the object's value expressed
|
||||
as the corresponding type. If the object is not precisely that
|
||||
|
|
@ -333,15 +338,15 @@ P3D_object_get_type_method(const P3D_object *object);
|
|||
|
||||
/* Return the object as a bool. */
|
||||
typedef bool
|
||||
P3D_object_get_bool_method(const P3D_object *object);
|
||||
P3D_object_get_bool_method(P3D_object *object);
|
||||
|
||||
/* Return the object as an integer. */
|
||||
typedef int
|
||||
P3D_object_get_int_method(const P3D_object *object);
|
||||
P3D_object_get_int_method(P3D_object *object);
|
||||
|
||||
/* Return the object as a floating-point number. */
|
||||
typedef double
|
||||
P3D_object_get_float_method(const P3D_object *object);
|
||||
P3D_object_get_float_method(P3D_object *object);
|
||||
|
||||
/* Get the object as a string. This method copies the string into the
|
||||
provided buffer, and returns the actual length of the internal
|
||||
|
|
@ -352,7 +357,7 @@ P3D_object_get_float_method(const P3D_object *object);
|
|||
buffer = NULL and buffer_length = 0 to return just the required
|
||||
size of the buffer. */
|
||||
typedef int
|
||||
P3D_object_get_string_method(const P3D_object *object,
|
||||
P3D_object_get_string_method(P3D_object *object,
|
||||
char *buffer, int buffer_length);
|
||||
|
||||
/* As above, but instead of the literal object data, returns a
|
||||
|
|
@ -362,23 +367,19 @@ P3D_object_get_string_method(const P3D_object *object,
|
|||
marks and escape characters from P3D_OBJECT_GET_REPR().
|
||||
Mechanically, this function works the same way as get_string(). */
|
||||
typedef int
|
||||
P3D_object_get_repr_method(const P3D_object *object,
|
||||
P3D_object_get_repr_method(P3D_object *object,
|
||||
char *buffer, int buffer_length);
|
||||
|
||||
/* Looks up a property on the object by name, i.e. a data member or a
|
||||
method. The return value is a newly-allocated P3D_object if the
|
||||
property exists, or NULL if it does not. If it is not NULL,
|
||||
ownership of the return value is transferred to the caller, who
|
||||
will be responsible for deleting it later. */
|
||||
method. The return value is a new-reference P3D_object if the
|
||||
property exists, or NULL if it does not. */
|
||||
typedef P3D_object *
|
||||
P3D_object_get_property_method(const P3D_object *object, const char *property);
|
||||
P3D_object_get_property_method(P3D_object *object, const char *property);
|
||||
|
||||
/* Changes the value at the indicated property. Any existing object
|
||||
already at the corresponding property is deleted. If the value
|
||||
object pointer is NULL, the property is deleted. Returns true on
|
||||
success, false on failure. The caller must have ownership of the
|
||||
value object before the call; after the call, ownership of the
|
||||
value object is transferred to this object. */
|
||||
pointer is NULL, the property is deleted. Returns true on success,
|
||||
false on failure. */
|
||||
typedef bool
|
||||
P3D_object_set_property_method(P3D_object *object, const char *property,
|
||||
P3D_object *value);
|
||||
|
|
@ -389,36 +390,32 @@ P3D_object_set_property_method(P3D_object *object, const char *property,
|
|||
a callable object. If method_name is empty or NULL, returns true
|
||||
if the object itself is callable. */
|
||||
typedef bool
|
||||
P3D_object_has_method_method(const P3D_object *object, const char *method_name);
|
||||
P3D_object_has_method_method(P3D_object *object, const char *method_name);
|
||||
|
||||
/* Invokes a named method on the object. If method_name is empty or
|
||||
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.
|
||||
array of P3D_objects as the list of parameters, and ownership of
|
||||
these objects' reference counts is not transferred with the call
|
||||
(you must still DECREF these objects afterwards).
|
||||
|
||||
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. */
|
||||
The return value is a new-reference P3D_object on success, or NULL
|
||||
on failure. */
|
||||
typedef P3D_object *
|
||||
P3D_object_call_method(const P3D_object *object, const char *method_name,
|
||||
P3D_object_call_method(P3D_object *object, const char *method_name,
|
||||
P3D_object *params[], int num_params);
|
||||
|
||||
/* Evaluates an arbitrary JavaScript expression in the context of the
|
||||
object.
|
||||
|
||||
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. */
|
||||
The return value is a new-reference P3D_object on success, or NULL
|
||||
on failure. */
|
||||
typedef P3D_object *
|
||||
P3D_object_eval_method(const P3D_object *object, const char *expression);
|
||||
P3D_object_eval_method(P3D_object *object, const char *expression);
|
||||
|
||||
/* This defines the class structure that implements all of the above
|
||||
methods. */
|
||||
typedef struct _P3D_class_definition {
|
||||
P3D_object_finish_method *_finish;
|
||||
P3D_object_copy_method *_copy;
|
||||
|
||||
P3D_object_get_type_method *_get_type;
|
||||
P3D_object_get_bool_method *_get_bool;
|
||||
|
|
@ -439,6 +436,7 @@ typedef struct _P3D_class_definition {
|
|||
/* And this structure defines the actual instances of P3D_object. */
|
||||
struct _P3D_object {
|
||||
const P3D_class_definition *_class;
|
||||
int _ref_count;
|
||||
|
||||
/* Additional opaque data may be stored here. */
|
||||
};
|
||||
|
|
@ -446,9 +444,6 @@ struct _P3D_object {
|
|||
/* These macros are defined for the convenience of invoking any of the
|
||||
above method functions on an object. */
|
||||
|
||||
#define P3D_OBJECT_FINISH(object) ((object)->_class->_finish((object)))
|
||||
#define P3D_OBJECT_COPY(object) ((object)->_class->_copy((object)))
|
||||
|
||||
#define P3D_OBJECT_GET_TYPE(object) ((object)->_class->_get_type((object)))
|
||||
#define P3D_OBJECT_GET_BOOL(object) ((object)->_class->_get_bool((object)))
|
||||
#define P3D_OBJECT_GET_INT(object) ((object)->_class->_get_int((object)))
|
||||
|
|
@ -463,58 +458,65 @@ struct _P3D_object {
|
|||
#define P3D_OBJECT_CALL(object, method_name, params, num_params) ((object)->_class->_call((object), (method_name), (params), (num_params)))
|
||||
#define P3D_OBJECT_EVAL(object, expression) ((object)->_class->_eval((object), (expression)))
|
||||
|
||||
/* These macros are provided to manipulate the reference count of the
|
||||
indicated object. Following Python's convention, XDECREF is
|
||||
provided to decrement the reference count for a pointer that might
|
||||
be NULL (it does nothing in the case of a NULL pointer). */
|
||||
|
||||
/* The following function types are once again meant to define
|
||||
actual function pointers to be found within the core API DLL. */
|
||||
#define P3D_OBJECT_INCREF(object) (++(object)->_ref_count)
|
||||
#define P3D_OBJECT_DECREF(object) { if (--(object)->_ref_count <= 0) { (object)->_class->_finish((object)); } }
|
||||
#define P3D_OBJECT_XDECREF(object) { if ((object) != (P3D_object *)NULL) { P3D_OBJECT_DECREF(object); } }
|
||||
|
||||
/* Returns a newly-allocated P3D_class_definition object, filled with
|
||||
generic function pointers that have reasonable default behavior for
|
||||
all methods. The host should use this function to get a clean
|
||||
|
||||
/* End of method pointer definitions. The following function types
|
||||
are once again meant to define actual function pointers to be found
|
||||
within the core API DLL. */
|
||||
|
||||
/* Returns a new P3D_class_definition object, filled with generic
|
||||
function pointers that have reasonable default behavior for all
|
||||
methods. The host should use this function to get a clean
|
||||
P3D_class_definition object before calling
|
||||
P3D_instance_set_browser_script_object() (see below). Note that this
|
||||
pointer will automatically be freed when P3D_finalize() is
|
||||
P3D_instance_set_browser_script_object() (see below). Note that
|
||||
this pointer will automatically be freed when P3D_finalize() is
|
||||
called. */
|
||||
typedef P3D_class_definition *
|
||||
P3D_make_class_definition_func();
|
||||
|
||||
/* Allocates a new P3D_object of type "undefined". This corresponds
|
||||
to the undefined or void type on JavaScript. It is similar to
|
||||
Python's None, but has a subtly different shade of meaning; we map
|
||||
it to an explicit Undefined instance in runp3d.py. */
|
||||
/* Returns a new-reference P3D_object of type "undefined". This
|
||||
corresponds to the undefined or void type on JavaScript. It is
|
||||
similar to Python's None, but has a subtly different shade of
|
||||
meaning; we map it to an explicit Undefined instance in
|
||||
runp3d.py. */
|
||||
typedef P3D_object *
|
||||
P3D_new_undefined_object_func();
|
||||
|
||||
/* Allocates a new P3D_object of type none. This value has no
|
||||
/* Returns a new-reference P3D_object of type none. This value has no
|
||||
particular value and corresponds to Python's None type or
|
||||
JavaScript's null type. */
|
||||
typedef P3D_object *
|
||||
P3D_new_none_object_func();
|
||||
|
||||
/* Allocates a new P3D_object of type bool. */
|
||||
/* Returns a new-reference P3D_object of type bool. */
|
||||
typedef P3D_object *
|
||||
P3D_new_bool_object_func(bool value);
|
||||
|
||||
/* Allocates a new P3D_object of type int. */
|
||||
/* Returns a new-reference P3D_object of type int. */
|
||||
typedef P3D_object *
|
||||
P3D_new_int_object_func(int value);
|
||||
|
||||
/* Allocates a new P3D_object of type float. */
|
||||
/* Returns a new-reference P3D_object of type float. */
|
||||
typedef P3D_object *
|
||||
P3D_new_float_object_func(double value);
|
||||
|
||||
/* Allocates a new P3D_object of type string. The supplied string is
|
||||
copied into the object and stored internally. */
|
||||
/* Returns a new-reference P3D_object of type string. The supplied
|
||||
string is copied into the object and stored internally. */
|
||||
typedef P3D_object *
|
||||
P3D_new_string_object_func(const char *string, int length);
|
||||
|
||||
/* 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
|
||||
query properties, and/or call methods, on the instance.
|
||||
|
||||
The return value from this function is a newly-allocated object;
|
||||
ownership of the object is passed to the caller, who should be
|
||||
responsible for deleting it eventually. */
|
||||
/* Returns a new-reference 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 query properties, and/or call methods, on the instance. */
|
||||
typedef P3D_object *
|
||||
P3D_instance_get_panda_script_object_func(P3D_instance *instance);
|
||||
|
||||
|
|
@ -528,8 +530,8 @@ P3D_instance_get_panda_script_object_func(P3D_instance *instance);
|
|||
have a custom P3D_class_definition pointer, which also must have
|
||||
been created by the host. The best way to create an appropriate
|
||||
class definition is call P3D_make_class_definition(), and then
|
||||
replace the function pointers for at least _finish, _copy,
|
||||
_get_property, _set_property, and _call. Set these pointers to the
|
||||
replace the function pointers for at least _finish, _get_property,
|
||||
_set_property, _has_method, and _call. Set these pointers to the
|
||||
host's own functions that make the appropriate changes in the DOM,
|
||||
or invoke the appropriate JavaScript functions.
|
||||
|
||||
|
|
@ -538,10 +540,10 @@ P3D_instance_get_panda_script_object_func(P3D_instance *instance);
|
|||
able to control the instance via P3D_instance_get_panda_script_object(),
|
||||
above.
|
||||
|
||||
Ownership of the object is passed into the instance. The caller
|
||||
must have freshly allocated the object, and should no longer store
|
||||
or delete it. The instance will eventually delete it by calling
|
||||
its _finish method. */
|
||||
Note that the object's constructor should initialize its reference
|
||||
count to 1. The instance will increment reference count as a
|
||||
result of this call; the caller is responsible for calling DECREF
|
||||
on the object after this call to remove its own reference. */
|
||||
typedef void
|
||||
P3D_instance_set_browser_script_object_func(P3D_instance *instance,
|
||||
P3D_object *object);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ extern ostream *nout_stream;
|
|||
// A convenience function for formatting a generic P3D_object to an
|
||||
// ostream.
|
||||
inline ostream &
|
||||
operator << (ostream &out, const P3D_object &value) {
|
||||
operator << (ostream &out, P3D_object &value) {
|
||||
int size = P3D_OBJECT_GET_REPR(&value, NULL, 0);
|
||||
char *buffer = new char[size];
|
||||
P3D_OBJECT_GET_REPR(&value, buffer, size);
|
||||
|
|
|
|||
|
|
@ -26,18 +26,13 @@ object_finish(P3D_object *object) {
|
|||
delete ((PPBrowserObject *)object);
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
object_copy(const P3D_object *object) {
|
||||
return new PPBrowserObject(*(const PPBrowserObject *)object);
|
||||
}
|
||||
|
||||
static int
|
||||
object_get_repr(const P3D_object *object, char *buffer, int buffer_length) {
|
||||
object_get_repr(P3D_object *object, char *buffer, int buffer_length) {
|
||||
return ((const PPBrowserObject *)object)->get_repr(buffer, buffer_length);
|
||||
}
|
||||
|
||||
static P3D_object *
|
||||
object_get_property(const P3D_object *object, const char *property) {
|
||||
object_get_property(P3D_object *object, const char *property) {
|
||||
return ((const PPBrowserObject *)object)->get_property(property);
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +43,7 @@ object_set_property(P3D_object *object, const char *property,
|
|||
}
|
||||
|
||||
static P3D_object *
|
||||
object_call(const P3D_object *object, const char *method_name,
|
||||
object_call(P3D_object *object, const char *method_name,
|
||||
P3D_object *params[], int num_params) {
|
||||
if (method_name == NULL) {
|
||||
method_name = "";
|
||||
|
|
@ -57,7 +52,7 @@ object_call(const P3D_object *object, const char *method_name,
|
|||
}
|
||||
|
||||
static P3D_object *
|
||||
object_eval(const P3D_object *object, const char *expression) {
|
||||
object_eval(P3D_object *object, const char *expression) {
|
||||
return ((const PPBrowserObject *)object)->eval(expression);
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +69,7 @@ PPBrowserObject(PPInstance *inst, NPObject *npobj) :
|
|||
_npobj(npobj)
|
||||
{
|
||||
_class = get_class_definition();
|
||||
_ref_count = 1;
|
||||
browser->retainobject(_npobj);
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +84,7 @@ PPBrowserObject(const PPBrowserObject ©) :
|
|||
_npobj(copy._npobj)
|
||||
{
|
||||
_class = get_class_definition();
|
||||
_ref_count = 1;
|
||||
browser->retainobject(_npobj);
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +95,7 @@ PPBrowserObject(const PPBrowserObject ©) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PPBrowserObject::
|
||||
~PPBrowserObject() {
|
||||
assert(_ref_count == 0);
|
||||
browser->releaseobject(_npobj);
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +160,6 @@ set_property(const string &property, P3D_object *value) {
|
|||
result = browser->setproperty(_instance->get_npp_instance(), _npobj,
|
||||
property_name, &npvalue);
|
||||
browser->releasevariantvalue(&npvalue);
|
||||
P3D_OBJECT_FINISH(value);
|
||||
|
||||
} else {
|
||||
// Delete the property.
|
||||
|
|
@ -268,7 +265,6 @@ get_class_definition() {
|
|||
// appropriate pointers.
|
||||
_browser_object_class = P3D_make_class_definition();
|
||||
_browser_object_class->_finish = &object_finish;
|
||||
_browser_object_class->_copy = &object_copy;
|
||||
|
||||
_browser_object_class->_get_repr = &object_get_repr;
|
||||
_browser_object_class->_get_property = &object_get_property;
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ get_panda_script_object() {
|
|||
// NPVariant, and stores it in result.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPInstance::
|
||||
p3dobj_to_variant(NPVariant *result, const P3D_object *object) {
|
||||
p3dobj_to_variant(NPVariant *result, P3D_object *object) {
|
||||
switch (P3D_OBJECT_GET_TYPE(object)) {
|
||||
case P3D_OT_undefined:
|
||||
VOID_TO_NPVARIANT(*result);
|
||||
|
|
@ -534,7 +534,7 @@ p3dobj_to_variant(NPVariant *result, const P3D_object *object) {
|
|||
|
||||
case P3D_OT_object:
|
||||
{
|
||||
PPPandaObject *ppobj = PPPandaObject::make_new(this, P3D_OBJECT_COPY(object));
|
||||
PPPandaObject *ppobj = PPPandaObject::make_new(this, object);
|
||||
OBJECT_TO_NPVARIANT(ppobj, *result);
|
||||
}
|
||||
break;
|
||||
|
|
@ -571,7 +571,7 @@ variant_to_p3dobj(const NPVariant *variant) {
|
|||
PPPandaObject *ppobject = (PPPandaObject *)object;
|
||||
P3D_object *obj = ppobject->get_p3d_object();
|
||||
logfile << "Found nested Panda Object " << obj << "\n" << flush;
|
||||
return P3D_OBJECT_COPY(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// It's a generic NPObject of some kind.
|
||||
|
|
@ -899,7 +899,7 @@ create_instance() {
|
|||
logfile << "Couldn't get window_object\n" << flush;
|
||||
}
|
||||
|
||||
const P3D_token *tokens = NULL;
|
||||
P3D_token *tokens = NULL;
|
||||
if (!_tokens.empty()) {
|
||||
tokens = &_tokens[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
NPObject *get_panda_script_object();
|
||||
|
||||
void p3dobj_to_variant(NPVariant *result, const P3D_object *object);
|
||||
void p3dobj_to_variant(NPVariant *result, P3D_object *object);
|
||||
P3D_object *variant_to_p3dobj(const NPVariant *variant);
|
||||
|
||||
static void output_np_variant(ostream &out, const NPVariant &result);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@
|
|||
// Access: Public
|
||||
// Description: Returns the p3d_object this PPPandaObject maps to. This
|
||||
// may be NULL if the object is not fully initialized.
|
||||
// If not NULL, this returns a new reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline P3D_object *PPPandaObject::
|
||||
get_p3d_object() const {
|
||||
if (_p3d_object != NULL) {
|
||||
P3D_OBJECT_INCREF(_p3d_object);
|
||||
}
|
||||
return _p3d_object;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,16 +53,17 @@ make_new(PPInstance *inst, P3D_object *p3d_object) {
|
|||
// Function: PPPandaObject::set_p3d_object
|
||||
// Access: Public
|
||||
// Description: Changes the p3d_object this PPPandaObject maps to. The
|
||||
// previous object, if any, is deleted. Ownership of
|
||||
// the new object is passed to the PPPandaObject.
|
||||
// new object's reference count is incremented, and the
|
||||
// previous object's is decremented.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPPandaObject::
|
||||
set_p3d_object(P3D_object *p3d_object) {
|
||||
if (_p3d_object != p3d_object) {
|
||||
if (_p3d_object != NULL) {
|
||||
P3D_OBJECT_FINISH(_p3d_object);
|
||||
}
|
||||
P3D_OBJECT_XDECREF(_p3d_object);
|
||||
_p3d_object = p3d_object;
|
||||
if (_p3d_object != NULL) {
|
||||
P3D_OBJECT_INCREF(_p3d_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +79,8 @@ void PPPandaObject::
|
|||
construct(PPInstance *inst, P3D_object *p3d_object) {
|
||||
logfile << "construct: " << this << "\n" << flush;
|
||||
_instance = inst;
|
||||
_p3d_object = p3d_object;
|
||||
_p3d_object = NULL;
|
||||
set_p3d_object(p3d_object);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -141,12 +143,16 @@ invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount,
|
|||
}
|
||||
|
||||
P3D_object **p3dargs = new P3D_object *[argCount];
|
||||
for (unsigned int i = 0; i < argCount; ++i) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < argCount; ++i) {
|
||||
p3dargs[i] = _instance->variant_to_p3dobj(&args[i]);
|
||||
}
|
||||
|
||||
P3D_object *value = P3D_OBJECT_CALL(_p3d_object, method_name.c_str(),
|
||||
p3dargs, argCount);
|
||||
for (i = 0; i < argCount; ++i) {
|
||||
P3D_OBJECT_DECREF(p3dargs[i]);
|
||||
}
|
||||
delete[] p3dargs;
|
||||
|
||||
if (value == NULL) {
|
||||
|
|
@ -156,7 +162,7 @@ invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount,
|
|||
|
||||
// We have the return value, and its value is stored in value.
|
||||
_instance->p3dobj_to_variant(result, value);
|
||||
P3D_OBJECT_FINISH(value);
|
||||
P3D_OBJECT_DECREF(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -177,12 +183,16 @@ invoke_default(const NPVariant *args, uint32_t argCount,
|
|||
}
|
||||
|
||||
P3D_object **p3dargs = new P3D_object *[argCount];
|
||||
for (unsigned int i = 0; i < argCount; ++i) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < argCount; ++i) {
|
||||
p3dargs[i] = _instance->variant_to_p3dobj(&args[i]);
|
||||
}
|
||||
|
||||
P3D_object *value = P3D_OBJECT_CALL(_p3d_object, "",
|
||||
p3dargs, argCount);
|
||||
for (i = 0; i < argCount; ++i) {
|
||||
P3D_OBJECT_DECREF(p3dargs[i]);
|
||||
}
|
||||
delete[] p3dargs;
|
||||
|
||||
if (value == NULL) {
|
||||
|
|
@ -192,7 +202,7 @@ invoke_default(const NPVariant *args, uint32_t argCount,
|
|||
|
||||
// We have the return value, and its value is stored in value.
|
||||
_instance->p3dobj_to_variant(result, value);
|
||||
P3D_OBJECT_FINISH(value);
|
||||
P3D_OBJECT_DECREF(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -239,7 +249,7 @@ get_property(NPIdentifier name, NPVariant *result) {
|
|||
|
||||
// We have the property, and its value is stored in value.
|
||||
_instance->p3dobj_to_variant(result, value);
|
||||
P3D_OBJECT_FINISH(value);
|
||||
P3D_OBJECT_DECREF(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -260,6 +270,7 @@ set_property(NPIdentifier name, const NPVariant *value) {
|
|||
|
||||
P3D_object *object = _instance->variant_to_p3dobj(value);
|
||||
bool result = P3D_OBJECT_SET_PROPERTY(_p3d_object, property_name.c_str(), object);
|
||||
P3D_OBJECT_DECREF(object);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue