more scriptability wip

This commit is contained in:
David Rose 2009-07-01 15:52:08 +00:00
parent 442ef013c4
commit a64a4f09c5
26 changed files with 572 additions and 31 deletions

View File

@ -79,9 +79,22 @@ get_int() const {
void P3DBoolVariant:: void P3DBoolVariant::
make_string(string &value) const { make_string(string &value) const {
if (_value) { if (_value) {
value = "1"; value = "True";
} else { } else {
value = "0"; value = "False";
} }
} }
////////////////////////////////////////////////////////////////////
// Function: P3DBoolVariant::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this variant.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DBoolVariant::
make_xml() const {
TiXmlElement *xvariant = new TiXmlElement("variant");
xvariant->SetAttribute("type", "bool");
xvariant->SetAttribute("value", (int)_value);
return xvariant;
}

View File

@ -33,6 +33,8 @@ public:
virtual int get_int() const; virtual int get_int() const;
virtual void make_string(string &value) const; virtual void make_string(string &value) const;
virtual TiXmlElement *make_xml() const;
private: private:
bool _value; bool _value;
}; };

View File

@ -24,7 +24,7 @@ P3DCInstance::
P3DCInstance(TiXmlElement *xinstance) : P3DCInstance(TiXmlElement *xinstance) :
_func(NULL) _func(NULL)
{ {
xinstance->Attribute("id", &_instance_id); xinstance->Attribute("instance_id", &_instance_id);
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -94,3 +94,17 @@ make_string(string &value) const {
value = strm.str(); value = strm.str();
} }
////////////////////////////////////////////////////////////////////
// Function: P3DFloatVariant::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this variant.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DFloatVariant::
make_xml() const {
TiXmlElement *xvariant = new TiXmlElement("variant");
xvariant->SetAttribute("type", "float");
xvariant->SetDoubleAttribute("value", _value);
return xvariant;
}

View File

@ -34,6 +34,8 @@ public:
virtual double get_float() const; virtual double get_float() const;
virtual void make_string(string &value) const; virtual void make_string(string &value) const;
virtual TiXmlElement *make_xml() const;
private: private:
double _value; double _value;
}; };

View File

@ -144,10 +144,10 @@ set_wparams(const P3DWindowParams &wparams) {
// Update the instance in the sub-process. // Update the instance in the sub-process.
if (_session != NULL) { if (_session != NULL) {
TiXmlDocument *doc = new TiXmlDocument; TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command"); TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "setup_window"); xcommand->SetAttribute("cmd", "setup_window");
xcommand->SetAttribute("id", get_instance_id()); xcommand->SetAttribute("instance_id", get_instance_id());
TiXmlElement *xwparams = _wparams.make_xml(); TiXmlElement *xwparams = _wparams.make_xml();
doc->LinkEndChild(decl); doc->LinkEndChild(decl);
@ -354,6 +354,24 @@ feed_url_stream(int unique_id,
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void P3DInstance:: void P3DInstance::
feed_value(int unique_id, P3DVariant *variant) { feed_value(int unique_id, P3DVariant *variant) {
if (_session != NULL) {
TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "feed_value");
xcommand->SetAttribute("instance_id", get_instance_id());
xcommand->SetAttribute("unique_id", unique_id);
if (variant != NULL) {
TiXmlElement *xvariant = variant->make_xml();
xcommand->LinkEndChild(xvariant);
}
doc->LinkEndChild(decl);
doc->LinkEndChild(xcommand);
_session->send_command(doc);
}
if (variant != NULL) { if (variant != NULL) {
delete variant; delete variant;
} }
@ -435,7 +453,7 @@ make_xml() {
assert(_got_fparams); assert(_got_fparams);
TiXmlElement *xinstance = new TiXmlElement("instance"); TiXmlElement *xinstance = new TiXmlElement("instance");
xinstance->SetAttribute("id", _instance_id); xinstance->SetAttribute("instance_id", _instance_id);
TiXmlElement *xfparams = _fparams.make_xml(); TiXmlElement *xfparams = _fparams.make_xml();
xinstance->LinkEndChild(xfparams); xinstance->LinkEndChild(xfparams);

View File

@ -83,3 +83,17 @@ make_string(string &value) const {
value = strm.str(); value = strm.str();
} }
////////////////////////////////////////////////////////////////////
// Function: P3DIntVariant::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this variant.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DIntVariant::
make_xml() const {
TiXmlElement *xvariant = new TiXmlElement("variant");
xvariant->SetAttribute("type", "int");
xvariant->SetAttribute("value", _value);
return xvariant;
}

View File

@ -33,6 +33,8 @@ public:
virtual int get_int() const; virtual int get_int() const;
virtual void make_string(string &value) const; virtual void make_string(string &value) const;
virtual TiXmlElement *make_xml() const;
private: private:
int _value; int _value;
}; };

View File

@ -14,10 +14,22 @@
#include "p3dListVariant.h" #include "p3dListVariant.h"
////////////////////////////////////////////////////////////////////
// Function: P3DListVariant::Default Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
P3DListVariant::
P3DListVariant() : P3DVariant(P3D_VT_list) {
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: P3DListVariant::Constructor // Function: P3DListVariant::Constructor
// Access: Public // Access: Public
// Description: // Description: Note that the ownership of the elements in the array
// (but not the array itself) is transferred to the
// list.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3DListVariant:: P3DListVariant::
P3DListVariant(P3DVariant * const elements[], int num_elements) : P3DListVariant(P3DVariant * const elements[], int num_elements) :
@ -90,12 +102,9 @@ make_string(string &value) const {
ostringstream strm; ostringstream strm;
strm << "["; strm << "[";
if (!_elements.empty()) { if (!_elements.empty()) {
string es; strm << *_elements[0];
_elements[0]->make_string(es);
strm << es;
for (size_t i = 1; i < _elements.size(); ++i) { for (size_t i = 1; i < _elements.size(); ++i) {
_elements[0]->make_string(es); strm << ", " << *_elements[i];
strm << ", " << es;
} }
} }
strm << "]"; strm << "]";
@ -128,3 +137,33 @@ get_list_item(int n) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: P3DListVariant::append_item
// Access: Public, Virtual
// Description: Appends a new item to the end of the list. Ownership
// of the item is transferred to the list.
////////////////////////////////////////////////////////////////////
void P3DListVariant::
append_item(P3DVariant *item) {
_elements.push_back(item);
}
////////////////////////////////////////////////////////////////////
// Function: P3DListVariant::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this variant.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DListVariant::
make_xml() const {
TiXmlElement *xvariant = new TiXmlElement("variant");
xvariant->SetAttribute("type", "list");
Elements::const_iterator ei;
for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
TiXmlElement *xchild = (*ei)->make_xml();
xvariant->LinkEndChild(xchild);
}
return xvariant;
}

View File

@ -24,6 +24,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class P3DListVariant : public P3DVariant { class P3DListVariant : public P3DVariant {
public: public:
P3DListVariant();
P3DListVariant(P3DVariant * const elements[], int num_elements); P3DListVariant(P3DVariant * const elements[], int num_elements);
P3DListVariant(const P3DListVariant &copy); P3DListVariant(const P3DListVariant &copy);
@ -36,6 +37,10 @@ public:
virtual int get_list_length() const; virtual int get_list_length() const;
virtual P3DVariant *get_list_item(int n) const; virtual P3DVariant *get_list_item(int n) const;
void append_item(P3DVariant *item);
virtual TiXmlElement *make_xml() const;
private: private:
typedef vector<P3DVariant *> Elements; typedef vector<P3DVariant *> Elements;
Elements _elements; Elements _elements;

View File

@ -54,3 +54,16 @@ void P3DNoneVariant::
make_string(string &value) const { make_string(string &value) const {
value = "None"; value = "None";
} }
////////////////////////////////////////////////////////////////////
// Function: P3DNoneVariant::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this variant.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DNoneVariant::
make_xml() const {
TiXmlElement *xvariant = new TiXmlElement("variant");
xvariant->SetAttribute("type", "none");
return xvariant;
}

View File

@ -31,6 +31,8 @@ public:
virtual P3DVariant *make_copy(); virtual P3DVariant *make_copy();
virtual bool get_bool() const; virtual bool get_bool() const;
virtual void make_string(string &value) const; virtual void make_string(string &value) const;
virtual TiXmlElement *make_xml() const;
}; };
#endif #endif

View File

@ -200,20 +200,26 @@ handle_command(TiXmlDocument *doc) {
P3DCInstance *inst = new P3DCInstance(xinstance); P3DCInstance *inst = new P3DCInstance(xinstance);
start_instance(inst, xinstance); start_instance(inst, xinstance);
} }
} else if (strcmp(cmd, "terminate_instance") == 0) { } else if (strcmp(cmd, "terminate_instance") == 0) {
int id; int id;
if (xcommand->Attribute("id", &id)) { if (xcommand->Attribute("instance_id", &id)) {
terminate_instance(id); terminate_instance(id);
} }
} else if (strcmp(cmd, "setup_window") == 0) { } else if (strcmp(cmd, "setup_window") == 0) {
int id; int id;
TiXmlElement *xwparams = xcommand->FirstChildElement("wparams"); TiXmlElement *xwparams = xcommand->FirstChildElement("wparams");
if (xwparams != (TiXmlElement *)NULL && if (xwparams != (TiXmlElement *)NULL &&
xcommand->Attribute("id", &id)) { xcommand->Attribute("instance_id", &id)) {
setup_window(id, xwparams); setup_window(id, xwparams);
} }
} else if (strcmp(cmd, "exit") == 0) { } else if (strcmp(cmd, "exit") == 0) {
terminate_session(); terminate_session();
} else if (strcmp(cmd, "feed_value") == 0) {
} else { } else {
nout << "Unhandled command " << cmd << "\n"; nout << "Unhandled command " << cmd << "\n";
@ -284,10 +290,12 @@ py_request_func(PyObject *args) {
} }
TiXmlDocument doc; TiXmlDocument doc;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xrequest = new TiXmlElement("request"); TiXmlElement *xrequest = new TiXmlElement("request");
xrequest->SetAttribute("id", instance_id); xrequest->SetAttribute("instance_id", instance_id);
xrequest->SetAttribute("rtype", request_type); xrequest->SetAttribute("rtype", request_type);
doc.LinkEndChild(decl);
doc.LinkEndChild(xrequest);
if (strcmp(request_type, "notify") == 0) { if (strcmp(request_type, "notify") == 0) {
// A general notification to be sent directly to the instance. // A general notification to be sent directly to the instance.
@ -297,8 +305,47 @@ py_request_func(PyObject *args) {
} }
xrequest->SetAttribute("message", message); xrequest->SetAttribute("message", message);
doc.LinkEndChild(decl); nout << "sending " << doc << "\n" << flush;
doc.LinkEndChild(xrequest); _pipe_write << doc << flush;
} else if (strcmp(request_type, "get_property") == 0) {
// A get-property request.
const char *property_name;
int unique_id;
if (!PyArg_ParseTuple(extra_args, "si", &property_name, &unique_id)) {
return NULL;
}
xrequest->SetAttribute("property_name", property_name);
xrequest->SetAttribute("unique_id", unique_id);
nout << "sending " << doc << "\n" << flush;
_pipe_write << doc << flush;
} else if (strcmp(request_type, "set_property") == 0) {
// A set-property request.
const char *property_name;
PyObject *value;
if (!PyArg_ParseTuple(extra_args, "sO", &property_name, &value)) {
return NULL;
}
xrequest->SetAttribute("property_name", property_name);
append_xml_variant(xrequest, value);
nout << "sending " << doc << "\n" << flush;
_pipe_write << doc << flush;
} else if (strcmp(request_type, "call") == 0) {
// A call-method request.
const char *property_name;
PyObject *params;
int unique_id;
if (!PyArg_ParseTuple(extra_args, "sOi", &property_name, &params, &unique_id)) {
return NULL;
}
xrequest->SetAttribute("property_name", property_name);
xrequest->SetAttribute("unique_id", unique_id);
append_xml_variant(xrequest, params);
nout << "sending " << doc << "\n" << flush; nout << "sending " << doc << "\n" << flush;
_pipe_write << doc << flush; _pipe_write << doc << flush;
@ -549,6 +596,103 @@ terminate_session() {
nout << "done calling stop()\n"; nout << "done calling stop()\n";
} }
////////////////////////////////////////////////////////////////////
// Function: P3DPythonRun::append_xml_variant
// Access: Private
// Description: Converts the indicated PyObject to the appropriate
// XML representation of a P3D_variant type, and appends
// it to the child list of the indicated element.
////////////////////////////////////////////////////////////////////
void P3DPythonRun::
append_xml_variant(TiXmlElement *xelement, PyObject *value) {
TiXmlElement *xvariant = new TiXmlElement("variant");
if (value == Py_None) {
// None.
xvariant->SetAttribute("type", "none");
} else if (PyBool_Check(value)) {
// A bool value.
xvariant->SetAttribute("type", "bool");
xvariant->SetAttribute("value", PyObject_IsTrue(value));
} else if (PyInt_Check(value)) {
// A plain integer value.
xvariant->SetAttribute("type", "int");
xvariant->SetAttribute("value", PyInt_AsLong(value));
} else if (PyLong_Check(value)) {
// A long integer value. This gets converted either as an integer
// or as a floating-point type, whichever fits.
long lvalue = PyLong_AsLong(value);
if (PyErr_Occurred()) {
// It won't fit as an integer; make it a double.
PyErr_Clear();
xvariant->SetAttribute("type", "float");
xvariant->SetDoubleAttribute("value", PyLong_AsDouble(value));
} else {
// It fits as an integer.
xvariant->SetAttribute("type", "int");
xvariant->SetAttribute("value", lvalue);
}
} else if (PyFloat_Check(value)) {
// A floating-point value.
xvariant->SetAttribute("type", "float");
xvariant->SetDoubleAttribute("value", PyFloat_AsDouble(value));
} else if (PyUnicode_Check(value)) {
// A unicode value. Convert to utf-8 for the XML encoding.
xvariant->SetAttribute("type", "string");
PyObject *as_str = PyUnicode_AsUTF8String(value);
if (as_str != NULL) {
char *buffer;
Py_ssize_t length;
if (PyString_AsStringAndSize(as_str, &buffer, &length) != -1) {
string str(buffer, length);
xvariant->SetAttribute("value", str);
}
Py_DECREF(as_str);
}
} else if (PyString_Check(value)) {
// A string value.
xvariant->SetAttribute("type", "string");
char *buffer;
Py_ssize_t length;
if (PyString_AsStringAndSize(value, &buffer, &length) != -1) {
string str(buffer, length);
xvariant->SetAttribute("value", str);
}
} else if (PySequence_Check(value)) {
// A sequence or list value.
xvariant->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);
append_xml_variant(xvariant, obj);
}
} else {
// Some other kind of object. Don't know what else to do with it;
// we'll make it a string.
xvariant->SetAttribute("type", "string");
PyObject *as_str = PyObject_Str(value);
if (as_str != NULL) {
char *buffer;
Py_ssize_t length;
if (PyString_AsStringAndSize(as_str, &buffer, &length) != -1) {
string str(buffer, length);
xvariant->SetAttribute("value", str);
}
Py_DECREF(as_str);
}
}
xelement->LinkEndChild(xvariant);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: P3DPythonRun::rt_thread_run // Function: P3DPythonRun::rt_thread_run
// Access: Private // Access: Private

View File

@ -80,6 +80,9 @@ private:
void terminate_session(); void terminate_session();
private:
void append_xml_variant(TiXmlElement *xelement, PyObject *value);
private: private:
// This method runs only within the read thread. // This method runs only within the read thread.

View File

@ -69,7 +69,7 @@ P3DSession::
if (_p3dpython_running) { if (_p3dpython_running) {
// Tell the process we're going away. // Tell the process we're going away.
TiXmlDocument doc; TiXmlDocument doc;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command"); TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "exit"); xcommand->SetAttribute("cmd", "exit");
doc.LinkEndChild(decl); doc.LinkEndChild(decl);
@ -136,7 +136,7 @@ start_instance(P3DInstance *inst) {
assert(inserted); assert(inserted);
TiXmlDocument *doc = new TiXmlDocument; TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command"); TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "start_instance"); xcommand->SetAttribute("cmd", "start_instance");
TiXmlElement *xinstance = inst->make_xml(); TiXmlElement *xinstance = inst->make_xml();
@ -169,10 +169,10 @@ start_instance(P3DInstance *inst) {
void P3DSession:: void P3DSession::
terminate_instance(P3DInstance *inst) { terminate_instance(P3DInstance *inst) {
TiXmlDocument *doc = new TiXmlDocument; TiXmlDocument *doc = new TiXmlDocument;
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
TiXmlElement *xcommand = new TiXmlElement("command"); TiXmlElement *xcommand = new TiXmlElement("command");
xcommand->SetAttribute("cmd", "terminate_instance"); xcommand->SetAttribute("cmd", "terminate_instance");
xcommand->SetAttribute("id", inst->get_instance_id()); xcommand->SetAttribute("instance_id", inst->get_instance_id());
doc->LinkEndChild(decl); doc->LinkEndChild(decl);
doc->LinkEndChild(xcommand); doc->LinkEndChild(xcommand);
@ -412,7 +412,7 @@ rt_handle_request(TiXmlDocument *doc) {
TiXmlElement *xrequest = doc->FirstChildElement("request"); TiXmlElement *xrequest = doc->FirstChildElement("request");
if (xrequest != (TiXmlElement *)NULL) { if (xrequest != (TiXmlElement *)NULL) {
int instance_id ; int instance_id ;
if (xrequest->Attribute("id", &instance_id)) { if (xrequest->Attribute("instance_id", &instance_id)) {
// Look up the particular instance this is related to. // Look up the particular instance this is related to.
ACQUIRE_LOCK(_instances_lock); ACQUIRE_LOCK(_instances_lock);
Instances::const_iterator ii; Instances::const_iterator ii;
@ -449,12 +449,102 @@ rt_make_p3d_request(TiXmlElement *xrequest) {
request->_request_type = P3D_RT_notify; request->_request_type = P3D_RT_notify;
request->_request._notify._message = strdup(message); request->_request._notify._message = strdup(message);
} }
} else if (strcmp(rtype, "get_property") == 0) {
const char *property_name = xrequest->Attribute("property_name");
int unique_id;
if (property_name != NULL && xrequest->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
request = new P3D_request;
request->_request_type = P3D_RT_get_property;
request->_request._get_property._property_name = strdup(property_name);
request->_request._get_property._unique_id = unique_id;
}
} else if (strcmp(rtype, "set_property") == 0) {
const char *property_name = xrequest->Attribute("property_name");
TiXmlElement *xvariant = xrequest->FirstChildElement("variant");
if (property_name != NULL && xvariant != NULL) {
request = new P3D_request;
request->_request_type = P3D_RT_set_property;
request->_request._set_property._property_name = strdup(property_name);
request->_request._set_property._value = rt_from_xml_variant(xvariant);
}
} else if (strcmp(rtype, "call") == 0) {
const char *property_name = xrequest->Attribute("property_name");
TiXmlElement *xvariant = xrequest->FirstChildElement("variant");
int unique_id;
if (property_name != NULL && xvariant != NULL &&
xrequest->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
request = new P3D_request;
request->_request_type = P3D_RT_call;
request->_request._call._property_name = strdup(property_name);
request->_request._call._params = rt_from_xml_variant(xvariant);
request->_request._call._unique_id = unique_id;
}
} else {
nout << "ignoring request of type " << rtype << "\n";
} }
} }
return request; return request;
} }
////////////////////////////////////////////////////////////////////
// Function: P3DSession::rt_from_xml_variant
// Access: Private
// Description: Converts the XML representation of the particular
// variant value into a corresponding P3DVariant object.
// Returns the newly-allocated object.
////////////////////////////////////////////////////////////////////
P3DVariant *P3DSession::
rt_from_xml_variant(TiXmlElement *xvariant) {
const char *type = xvariant->Attribute("type");
if (strcmp(type, "none") == 0) {
return new P3DNoneVariant;
} else if (strcmp(type, "bool") == 0) {
int value;
if (xvariant->QueryIntAttribute("value", &value) == TIXML_SUCCESS) {
return new P3DBoolVariant(value != 0);
}
} else if (strcmp(type, "int") == 0) {
int value;
if (xvariant->QueryIntAttribute("value", &value) == TIXML_SUCCESS) {
return new P3DIntVariant(value);
}
} else if (strcmp(type, "float") == 0) {
double value;
if (xvariant->QueryDoubleAttribute("value", &value) == TIXML_SUCCESS) {
return new P3DFloatVariant(value);
}
} else if (strcmp(type, "string") == 0) {
// Using the string form here instead of the char * form, so we
// don't get tripped up on embedded null characters.
const string *value = xvariant->Attribute(string("value"));
if (value != NULL) {
return new P3DStringVariant(*value);
}
} else if (strcmp(type, "list") == 0) {
P3DListVariant *list = new P3DListVariant;
TiXmlElement *xchild = xvariant->FirstChildElement("variant");
while (xchild != NULL) {
list->append_item(rt_from_xml_variant(xchild));
xchild = xchild->NextSiblingElement("variant");
}
return list;
}
// Something went wrong in decoding.
return new P3DNoneVariant;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: P3DSession::rt_terminate // Function: P3DSession::rt_terminate
// Access: Private // Access: Private

View File

@ -61,6 +61,7 @@ private:
void rt_terminate(); void rt_terminate();
void rt_handle_request(TiXmlDocument *doc); void rt_handle_request(TiXmlDocument *doc);
P3D_request *rt_make_p3d_request(TiXmlElement *xrequest); P3D_request *rt_make_p3d_request(TiXmlElement *xrequest);
P3DVariant *rt_from_xml_variant(TiXmlElement *xvariant);
#ifdef _WIN32 #ifdef _WIN32
static DWORD WINAPI win_rt_thread_run(LPVOID data); static DWORD WINAPI win_rt_thread_run(LPVOID data);

View File

@ -20,9 +20,9 @@
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3DStringVariant:: P3DStringVariant::
P3DStringVariant(const char *value, int length) : P3DStringVariant(const string &value) :
P3DVariant(P3D_VT_string), P3DVariant(P3D_VT_string),
_value(value, length) _value(value)
{ {
} }
@ -79,3 +79,58 @@ make_string(string &value) const {
value = _value; value = _value;
} }
////////////////////////////////////////////////////////////////////
// Function: P3DStringVariant::make_xml
// Access: Public, Virtual
// Description: Allocates and returns a new XML structure
// corresponding to this variant.
////////////////////////////////////////////////////////////////////
TiXmlElement *P3DStringVariant::
make_xml() const {
TiXmlElement *xvariant = new TiXmlElement("variant");
xvariant->SetAttribute("type", "string");
xvariant->SetAttribute("value", _value);
return xvariant;
}
////////////////////////////////////////////////////////////////////
// Function: P3DStringVariant::output
// Access: Public, Virtual
// Description: Writes a formatted representation of the value to the
// indicated string. This is intended for developer
// assistance.
////////////////////////////////////////////////////////////////////
void P3DStringVariant::
output(ostream &out) const {
out << '"';
for (string::const_iterator si = _value.begin(); si != _value.end(); ++si) {
if (isprint(*si)) {
switch (*si) {
case '"':
out << "\\\x22";
break;
default:
out << *si;
}
} else {
switch (*si) {
case '\n':
out << "\\n";
break;
case '\t':
out << "\\t";
break;
default:
{
char buffer[128];
sprintf(buffer, "%02x", (unsigned char)(*si));
out << "\\x" << buffer;
}
}
}
}
out << '"';
}

View File

@ -24,7 +24,7 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class P3DStringVariant : public P3DVariant { class P3DStringVariant : public P3DVariant {
public: public:
P3DStringVariant(const char *value, int length); P3DStringVariant(const string &value);
P3DStringVariant(const P3DStringVariant &copy); P3DStringVariant(const P3DStringVariant &copy);
public: public:
@ -34,6 +34,10 @@ public:
virtual bool get_bool() const; virtual bool get_bool() const;
virtual void make_string(string &value) const; virtual void make_string(string &value) const;
virtual TiXmlElement *make_xml() const;
virtual void output(ostream &out) const;
private: private:
string _value; string _value;
}; };

View File

@ -100,3 +100,17 @@ P3DVariant *P3DVariant::
get_list_item(int n) const { get_list_item(int n) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: P3DVariant::output
// Access: Public, Virtual
// Description: Writes a formatted representation of the value to the
// indicated string. This is intended for developer
// assistance.
////////////////////////////////////////////////////////////////////
void P3DVariant::
output(ostream &out) const {
string value;
make_string(value);
out << value;
}

View File

@ -44,9 +44,18 @@ public:
virtual int get_list_length() const; virtual int get_list_length() const;
virtual P3DVariant *get_list_item(int n) const; virtual P3DVariant *get_list_item(int n) const;
virtual TiXmlElement *make_xml() const=0;
virtual void output(ostream &out) const;
}; };
#include "p3dVariant.I" #include "p3dVariant.I"
inline ostream &operator << (ostream &out, const P3DVariant &variant) {
variant.output(out);
return out;
}
#endif #endif

View File

@ -120,7 +120,9 @@ void
P3D_variant_finish(P3D_variant *variant) { P3D_variant_finish(P3D_variant *variant) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized()); assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_lock); ACQUIRE_LOCK(_lock);
delete (P3DVariant *)variant; if (variant != NULL) {
delete (P3DVariant *)variant;
}
RELEASE_LOCK(_lock); RELEASE_LOCK(_lock);
} }
@ -200,7 +202,7 @@ P3D_variant *
P3D_new_string_variant(const char *value, int length) { P3D_new_string_variant(const char *value, int length) {
assert(P3DInstanceManager::get_global_ptr()->is_initialized()); assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_lock); ACQUIRE_LOCK(_lock);
P3D_variant *result = new P3DStringVariant(value, length); P3D_variant *result = new P3DStringVariant(string(value, length));
RELEASE_LOCK(_lock); RELEASE_LOCK(_lock);
return result; return result;
} }

View File

@ -302,30 +302,102 @@ handle_request(P3D_request *request) {
break; break;
case P3D_RT_get_url: case P3D_RT_get_url:
cerr << "Got P3D_RT_get_url\n"; cerr << "Got P3D_RT_get_url: " << request->_request._get_url._url
<< "\n";
{ {
URLGetter *getter = new URLGetter URLGetter *getter = new URLGetter
(request->_instance, request->_request._get_url._unique_id, (request->_instance, request->_request._get_url._unique_id,
URLSpec(request->_request._get_url._url), ""); URLSpec(request->_request._get_url._url), "");
_url_getters.insert(getter); _url_getters.insert(getter);
handled = true;
} }
break; break;
case P3D_RT_post_url: case P3D_RT_post_url:
cerr << "Got P3D_RT_post_url\n"; cerr << "Got P3D_RT_post_url: " << request->_request._post_url._url
<< "\n";
{ {
URLGetter *getter = new URLGetter URLGetter *getter = new URLGetter
(request->_instance, request->_request._post_url._unique_id, (request->_instance, request->_request._post_url._unique_id,
URLSpec(request->_request._post_url._url), URLSpec(request->_request._post_url._url),
string(request->_request._post_url._post_data, request->_request._post_url._post_data_size)); string(request->_request._post_url._post_data, request->_request._post_url._post_data_size));
_url_getters.insert(getter); _url_getters.insert(getter);
handled = true;
} }
break; break;
case P3D_RT_notify: case P3D_RT_notify:
cerr << "Got P3D_RT_notify: " << request->_request._notify._message
<< "\n";
// Ignore notifications. // Ignore notifications.
break; break;
case P3D_RT_get_property:
cerr << "Got P3D_RT_get_property: "
<< request->_request._get_property._property_name << "\n";
{
Properties::iterator pi =
_properties.find(request->_request._get_property._property_name);
if (pi != _properties.end()) {
// The named property has been set.
P3D_variant *dup_value = P3D_variant_copy((*pi).second);
P3D_instance_feed_value(request->_instance,
request->_request._get_property._unique_id,
dup_value);
} else {
// No such property set.
P3D_instance_feed_value(request->_instance,
request->_request._get_property._unique_id,
NULL);
}
handled = true;
}
break;
case P3D_RT_set_property:
cerr << "Got P3D_RT_set_property: "
<< request->_request._set_property._property_name << "\n";
{
// Also output the new value.
int buffer_size =
P3D_variant_get_string_length(request->_request._set_property._value);
char *buffer = (char *)alloca(buffer_size);
P3D_variant_extract_string(request->_request._set_property._value, buffer, buffer_size);
cerr.write(buffer, buffer_size);
cerr << "\n";
Properties::iterator pi =
_properties.insert(Properties::value_type(request->_request._set_property._property_name, NULL)).first;
if ((*pi).second != NULL) {
// Delete the original property.
P3D_variant_finish((*pi).second);
}
(*pi).second =
P3D_variant_copy(request->_request._set_property._value);
handled = true;
}
break;
case P3D_RT_call:
cerr << "Got P3D_RT_call: "
<< request->_request._call._property_name << "\n";
{
// Also output the parameter list.
int buffer_size =
P3D_variant_get_string_length(request->_request._call._params);
char *buffer = (char *)alloca(buffer_size);
P3D_variant_extract_string(request->_request._call._params, buffer, buffer_size);
cerr.write(buffer, buffer_size);
cerr << "\n";
// We don't have a mechanism for actually calling anything, though.
P3D_instance_feed_value(request->_instance,
request->_request._call._unique_id,
NULL);
handled = true;
}
break;
default: default:
// Some request types are not handled. // Some request types are not handled.
cerr << "Unhandled request: " << request->_request_type << "\n"; cerr << "Unhandled request: " << request->_request_type << "\n";

View File

@ -60,6 +60,11 @@ private:
typedef pset<P3D_instance *> Instances; typedef pset<P3D_instance *> Instances;
Instances _instances; Instances _instances;
// We maintain a table of properties in the "browser", mainly so we
// can test this feature of the core plugin API.
typedef pmap<string, P3D_variant *> Properties;
Properties _properties;
// This nested class keeps track of active URL requests. // This nested class keeps track of active URL requests.
class URLGetter { class URLGetter {
public: public:

View File

@ -0,0 +1,9 @@
""" This module serves as a placeholder for the global AppRunner
object, which only exists when we are running a .p3d file via
runp3d.py or via the Panda3D plugin or standalone executable.
This is needed for apps that start themselves by importing
DirectStart; it provides a place for these apps to look for
the AppRunner at startup. """
appRunner = None

View File

@ -41,6 +41,7 @@ import SfxPlayer
if __debug__: if __debug__:
from direct.directutil import DeltaProfiler from direct.directutil import DeltaProfiler
import OnScreenDebug import OnScreenDebug
import AppRunnerGlobal
__builtin__.FADE_SORT_INDEX = 1000 __builtin__.FADE_SORT_INDEX = 1000
__builtin__.NO_FADE_SORT_INDEX = 2000 __builtin__.NO_FADE_SORT_INDEX = 2000
@ -63,6 +64,9 @@ class ShowBase(DirectObject.DirectObject):
self.mainDir = Filename.fromOsSpecific(maindir).getFullpath() self.mainDir = Filename.fromOsSpecific(maindir).getFullpath()
ExecutionEnvironment.setEnvironmentVariable("MAIN_DIR", self.mainDir) ExecutionEnvironment.setEnvironmentVariable("MAIN_DIR", self.mainDir)
# The appRunner should have been created by the time ShowBase
# has been.
self.appRunner = AppRunnerGlobal.appRunner
#debug running multiplier #debug running multiplier
self.debugRunningMultiplier = 4 self.debugRunningMultiplier = 4

View File

@ -25,6 +25,7 @@ from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, getModelPath, HTTPClient from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, getModelPath, HTTPClient
from direct.stdpy import file from direct.stdpy import file
from direct.task.TaskManagerGlobal import taskMgr from direct.task.TaskManagerGlobal import taskMgr
from direct.showbase import AppRunnerGlobal
import os import os
import __builtin__ import __builtin__
@ -54,9 +55,13 @@ class AppRunner(DirectObject):
# This is the default requestFunc that is installed if we # This is the default requestFunc that is installed if we
# never call setRequestFunc(). # never call setRequestFunc().
def defaultRequestFunc(*args): def defaultRequestFunc(*args):
print "Ignoring request func: %s" % (args,) print "Ignoring request: %s" % (args,)
self.requestFunc = defaultRequestFunc self.requestFunc = defaultRequestFunc
# Store our pointer so DirectStart-based apps can find us.
if AppRunnerGlobal.appRunner is None:
AppRunnerGlobal.appRunner = self
def initPackedAppEnvironment(self): def initPackedAppEnvironment(self):
""" This function sets up the Python environment suitably for """ This function sets up the Python environment suitably for
running a packed app. It should only run once in any given running a packed app. It should only run once in any given