replace set_property/get_property with evaluate
This commit is contained in:
parent
fb630dc7cf
commit
3d4b534a68
|
|
@ -220,16 +220,21 @@ handle_command(TiXmlDocument *doc) {
|
|||
|
||||
} else if (strcmp(cmd, "feed_value") == 0) {
|
||||
int instance_id, unique_id;
|
||||
TiXmlElement *xvalue = xcommand->FirstChildElement("value");
|
||||
if (xvalue != (TiXmlElement *)NULL &&
|
||||
xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS &&
|
||||
if (xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS &&
|
||||
xcommand->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
|
||||
// TODO: deal with instance_id.
|
||||
PyObject *value = from_xml_value(xvalue);
|
||||
PyObject *result = PyObject_CallMethod
|
||||
(_runner, (char*)"feedValue", (char*)"iO", unique_id, value);
|
||||
Py_DECREF(value);
|
||||
Py_XDECREF(result);
|
||||
TiXmlElement *xvalue = xcommand->FirstChildElement("value");
|
||||
if (xvalue != NULL) {
|
||||
PyObject *value = from_xml_value(xvalue);
|
||||
PyObject *result = PyObject_CallMethod
|
||||
(_runner, (char*)"feedValue", (char*)"iOi", unique_id, value, true);
|
||||
Py_DECREF(value);
|
||||
Py_XDECREF(result);
|
||||
} else {
|
||||
PyObject *result = PyObject_CallMethod
|
||||
(_runner, (char*)"feedValue", (char*)"iOi", unique_id, Py_None, false);
|
||||
Py_XDECREF(result);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -319,47 +324,19 @@ py_request_func(PyObject *args) {
|
|||
nout << "sending " << doc << "\n" << flush;
|
||||
_pipe_write << doc << flush;
|
||||
|
||||
} else if (strcmp(request_type, "get_property") == 0) {
|
||||
// A get-property request.
|
||||
const char *property_name;
|
||||
} else if (strcmp(request_type, "evaluate") == 0) {
|
||||
// An evaluate request.
|
||||
const char *expression;
|
||||
int unique_id;
|
||||
if (!PyArg_ParseTuple(extra_args, "si", &property_name, &unique_id)) {
|
||||
if (!PyArg_ParseTuple(extra_args, "si", &expression, &unique_id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xrequest->SetAttribute("property_name", property_name);
|
||||
xrequest->SetAttribute("expression", expression);
|
||||
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);
|
||||
xrequest->LinkEndChild(make_xml_value(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, ¶ms, &unique_id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xrequest->SetAttribute("property_name", property_name);
|
||||
xrequest->SetAttribute("unique_id", unique_id);
|
||||
xrequest->LinkEndChild(make_xml_value(params));
|
||||
nout << "sending " << doc << "\n" << flush;
|
||||
_pipe_write << doc << flush;
|
||||
|
||||
} else {
|
||||
string message = string("Unsupported request type: ") + string(request_type);
|
||||
PyErr_SetString(PyExc_ValueError, message.c_str());
|
||||
|
|
|
|||
|
|
@ -450,37 +450,14 @@ rt_make_p3d_request(TiXmlElement *xrequest) {
|
|||
request->_request._notify._message = strdup(message);
|
||||
}
|
||||
|
||||
} else if (strcmp(rtype, "get_property") == 0) {
|
||||
const char *property_name = xrequest->Attribute("property_name");
|
||||
} else if (strcmp(rtype, "evaluate") == 0) {
|
||||
const char *expression = xrequest->Attribute("expression");
|
||||
int unique_id;
|
||||
if (property_name != NULL && xrequest->QueryIntAttribute("unique_id", &unique_id) == TIXML_SUCCESS) {
|
||||
if (expression != 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 *xvalue = xrequest->FirstChildElement("value");
|
||||
if (property_name != NULL && xvalue != 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_value(xvalue);
|
||||
}
|
||||
|
||||
} else if (strcmp(rtype, "call") == 0) {
|
||||
const char *property_name = xrequest->Attribute("property_name");
|
||||
TiXmlElement *xvalue = xrequest->FirstChildElement("value");
|
||||
int unique_id;
|
||||
if (property_name != NULL && xvalue != 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_value(xvalue);
|
||||
request->_request._call._unique_id = unique_id;
|
||||
request->_request_type = P3D_RT_evaluate;
|
||||
request->_request._evaluate._expression = strdup(expression);
|
||||
request->_request._evaluate._unique_id = unique_id;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -451,9 +451,7 @@ typedef enum {
|
|||
P3D_RT_get_url,
|
||||
P3D_RT_post_url,
|
||||
P3D_RT_notify,
|
||||
P3D_RT_get_property,
|
||||
P3D_RT_set_property,
|
||||
P3D_RT_call,
|
||||
P3D_RT_evaluate,
|
||||
} P3D_request_type;
|
||||
|
||||
/* Structures corresponding to the request types in the above enum. */
|
||||
|
|
@ -497,44 +495,18 @@ typedef struct {
|
|||
const char *_message;
|
||||
} P3D_request_notify;
|
||||
|
||||
/* A request to query a property on a host object. The property_name
|
||||
will be a dot-delimited string corresponding to a nested object.
|
||||
It should begin with "window." for the window object and
|
||||
"document." for the DOM object that loaded the plugin. The host
|
||||
should respond to this request by calling P3D_instance_feed_value()
|
||||
with the given unique_id and the requested value, or NULL if the
|
||||
named property does not exist. */
|
||||
/* A request to evaluate a Javascript expression or statement. The
|
||||
expression will be evaluated in the context of the parent window.
|
||||
It is particularly useful for querying document state, such as
|
||||
"document.form.username.value", or for changing this state, such as
|
||||
"document.form.choose.red.select = 1". After evaluating the
|
||||
expression, the host should return the response to this request by
|
||||
calling P3D_instance_feed_value() with the given unique_id and the
|
||||
result value, or NULL if there was an error with the expression. */
|
||||
typedef struct {
|
||||
const char *_property_name;
|
||||
const char *_expression;
|
||||
int _unique_id;
|
||||
} P3D_request_get_property;
|
||||
|
||||
/* A request to change or set a property on a host object. The
|
||||
property_name will be a dot-delimited string corresponding to a
|
||||
nested object, as above. _value may be NULL to indicate a request
|
||||
to delete the named property. The host does *not* receive
|
||||
ownership of the _value pointer and should not store it or delete
|
||||
it. The host need not respond to this event (other than by calling
|
||||
P3D_request_finish()). */
|
||||
typedef struct {
|
||||
const char *_property_name;
|
||||
const P3D_value *_value;
|
||||
} P3D_request_set_property;
|
||||
|
||||
/* A request to call a function on a host object. The property_name
|
||||
will be a dot-delimited string corresponding to a nested object, as
|
||||
above. The _params pointer will be a list value, which contains
|
||||
the parameter values to pass to the function. The host does not
|
||||
receive ownership of the _params pointer and should not store it or
|
||||
delete it. The host should respond to this request by calling
|
||||
P3D_instance_feed_value() with the given unique_id and the return
|
||||
value of the function, or NULL if the function does not exist or is
|
||||
not a callable object. */
|
||||
typedef struct {
|
||||
const char *_property_name;
|
||||
const P3D_value *_params;
|
||||
int _unique_id;
|
||||
} P3D_request_call;
|
||||
} P3D_request_evaluate;
|
||||
|
||||
/* This is the overall structure that represents a single request. It
|
||||
is returned by P3D_instance_get_request(). */
|
||||
|
|
@ -546,9 +518,7 @@ typedef struct {
|
|||
P3D_request_get_url _get_url;
|
||||
P3D_request_post_url _post_url;
|
||||
P3D_request_notify _notify;
|
||||
P3D_request_get_property _get_property;
|
||||
P3D_request_set_property _set_property;
|
||||
P3D_request_call _call;
|
||||
P3D_request_evaluate _evaluate;
|
||||
} _request;
|
||||
} P3D_request;
|
||||
|
||||
|
|
@ -650,13 +620,12 @@ P3D_instance_feed_url_stream_func(P3D_instance *instance, int unique_id,
|
|||
const void *this_data,
|
||||
size_t this_data_size);
|
||||
|
||||
/* This function is called by the host in response to a get_property
|
||||
or call request. The instance and unique_id parameters are from
|
||||
the original request; the value should be a freshly-allocated
|
||||
P3D_value that represents the requested property value or the
|
||||
return value from the function call, or NULL on error. Ownership
|
||||
of the value value is passed into the plugin; the host should
|
||||
*not* call P3D_value_finish() on this pointer. */
|
||||
/* This function is called by the host in response to an evaulate
|
||||
request. The instance and unique_id parameters are from the
|
||||
original request; the value should be a freshly-allocated P3D_value
|
||||
that represents the value of the evaluated expression, or NULL on
|
||||
error. Ownership of the value value is passed into the plugin; the
|
||||
host should *not* call P3D_value_finish() on this pointer. */
|
||||
typedef void
|
||||
P3D_instance_feed_value_func(P3D_instance *instance, int unique_id,
|
||||
P3D_value *value);
|
||||
|
|
|
|||
|
|
@ -369,7 +369,17 @@ handle_request(P3D_request *request) {
|
|||
browser->geturlnotify(_npp_instance, request->_request._get_url._url,
|
||||
NULL, req);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case P3D_RT_evaluate:
|
||||
{
|
||||
logfile << "Got P3D_RT_evaluate: "
|
||||
<< request->_request._evaluate._expression << "\n"
|
||||
<< flush;
|
||||
const string &expression = request->_request._evaluate._expression;
|
||||
int unique_id = request->_request._evaluate._unique_id;
|
||||
handle_evaluate(expression, unique_id);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -597,3 +607,95 @@ send_window() {
|
|||
0, 0, _window.width, _window.height,
|
||||
parent_window);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPInstance::handle_evaluate
|
||||
// Access: Private
|
||||
// Description: Evaluates the script within the window, as requested
|
||||
// by the Panda code.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPInstance::
|
||||
handle_evaluate(const string &expression, int unique_id) {
|
||||
NPObject *window = NULL;
|
||||
if (browser->getvalue(_npp_instance, NPNVWindowNPObject, &window) == NPERR_NO_ERROR) {
|
||||
logfile << "Got object for NPNVWindowNPObject: " << window << "\n";
|
||||
|
||||
NPString script;
|
||||
script.utf8characters = expression.c_str();
|
||||
script.utf8length = expression.length();
|
||||
NPVariant result;
|
||||
if (browser->evaluate(_npp_instance, window, &script, &result)) {
|
||||
logfile << "Evaluated, result = ";
|
||||
show_np_variant(result);
|
||||
logfile << "\n" << flush;
|
||||
|
||||
P3D_value *value = np_variant_to_value(result);
|
||||
browser->releasevariantvalue(&result);
|
||||
|
||||
P3D_instance_feed_value(_p3d_inst, unique_id, value);
|
||||
|
||||
} else {
|
||||
logfile << "Couldn't evaluate\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
logfile << "Couldn't get object for NPNVWindowNPObject\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPInstance::show_np_variant
|
||||
// Access: Private
|
||||
// Description: Outputs the variant value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPInstance::
|
||||
show_np_variant(const NPVariant &result) {
|
||||
if (NPVARIANT_IS_NULL(result)) {
|
||||
logfile << "null";
|
||||
} else if (NPVARIANT_IS_VOID(result)) {
|
||||
logfile << "void";
|
||||
} else if (NPVARIANT_IS_BOOLEAN(result)) {
|
||||
logfile << "bool " << NPVARIANT_TO_BOOLEAN(result);
|
||||
} else if (NPVARIANT_IS_INT32(result)) {
|
||||
logfile << "int " << NPVARIANT_TO_INT32(result);
|
||||
} else if (NPVARIANT_IS_DOUBLE(result)) {
|
||||
logfile << "double " << NPVARIANT_TO_DOUBLE(result);
|
||||
} else if (NPVARIANT_IS_STRING(result)) {
|
||||
NPString str = NPVARIANT_TO_STRING(result);
|
||||
logfile << "string " << string(str.utf8characters, str.utf8length);
|
||||
} else if (NPVARIANT_IS_OBJECT(result)) {
|
||||
NPObject *child = NPVARIANT_TO_OBJECT(result);
|
||||
logfile << "object " << child;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPInstance::np_variant_to_value
|
||||
// Access: Private
|
||||
// Description: Returns a fresly-allocated P3D_value object
|
||||
// corresponding to the indicated NPVariant.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3D_value *PPInstance::
|
||||
np_variant_to_value(const NPVariant &result) {
|
||||
if (NPVARIANT_IS_NULL(result)) {
|
||||
return NULL;
|
||||
} else if (NPVARIANT_IS_VOID(result)) {
|
||||
return P3D_new_none_value();
|
||||
} else if (NPVARIANT_IS_BOOLEAN(result)) {
|
||||
return P3D_new_bool_value(NPVARIANT_TO_BOOLEAN(result));
|
||||
} else if (NPVARIANT_IS_INT32(result)) {
|
||||
return P3D_new_int_value(NPVARIANT_TO_INT32(result));
|
||||
} else if (NPVARIANT_IS_DOUBLE(result)) {
|
||||
return P3D_new_float_value(NPVARIANT_TO_DOUBLE(result));
|
||||
} else if (NPVARIANT_IS_STRING(result)) {
|
||||
NPString str = NPVARIANT_TO_STRING(result);
|
||||
return P3D_new_string_value(str.utf8characters, str.utf8length);
|
||||
} else if (NPVARIANT_IS_OBJECT(result)) {
|
||||
// TODO?
|
||||
return P3D_new_none_value();
|
||||
// NPVARIANT_TO_OBJECT(result);
|
||||
}
|
||||
|
||||
// Huh, what is this?
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ private:
|
|||
void create_instance();
|
||||
void send_window();
|
||||
|
||||
void handle_evaluate(const string &expression, int unique_id);
|
||||
void show_np_variant(const NPVariant &result);
|
||||
P3D_value *np_variant_to_value(const NPVariant &result);
|
||||
|
||||
private:
|
||||
NPP _npp_instance;
|
||||
unsigned int _npp_mode;
|
||||
|
|
|
|||
|
|
@ -396,6 +396,23 @@ NPP_URLNotify(NPP instance, const char *url,
|
|||
NPError
|
||||
NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
|
||||
logfile << "GetValue " << variable << "\n";
|
||||
|
||||
/*
|
||||
if (variable == NPPVpluginScriptableNPObject) {
|
||||
static NPObject *object = NULL;
|
||||
if (object == NULL) {
|
||||
static NPClass npclass;
|
||||
memset(&npclass, 0, sizeof(npclass));
|
||||
npclass.structVersion = NP_CLASS_STRUCT_VERSION;
|
||||
object = browser->createobject(instance, &npclass);
|
||||
assert(object != NULL);
|
||||
}
|
||||
|
||||
*(NPObject **)value = object;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
*/
|
||||
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -406,68 +406,18 @@ handle_request(P3D_request *request) {
|
|||
// Ignore notifications.
|
||||
break;
|
||||
|
||||
case P3D_RT_get_property:
|
||||
cerr << "Got P3D_RT_get_property: "
|
||||
<< request->_request._get_property._property_name << "\n";
|
||||
case P3D_RT_evaluate:
|
||||
cerr << "Got P3D_RT_evaluate: "
|
||||
<< request->_request._evaluate._expression << "\n";
|
||||
{
|
||||
Properties::iterator pi =
|
||||
_properties.find(request->_request._get_property._property_name);
|
||||
if (pi != _properties.end()) {
|
||||
// The named property has been set.
|
||||
P3D_value *dup_value = P3D_value_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_value_get_string_length(request->_request._set_property._value);
|
||||
char *buffer = (char *)alloca(buffer_size);
|
||||
P3D_value_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_value_finish((*pi).second);
|
||||
}
|
||||
(*pi).second =
|
||||
P3D_value_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_value_get_string_length(request->_request._call._params);
|
||||
char *buffer = (char *)alloca(buffer_size);
|
||||
P3D_value_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.
|
||||
// In this standalone executable, every expression evaluates to
|
||||
// itself as a string. We do this just to help debug the
|
||||
// expression passing to and from the low-level Python code.
|
||||
const string &expression = request->_request._evaluate._expression;
|
||||
P3D_value *value = P3D_new_string_value(expression.data(), expression.length());
|
||||
P3D_instance_feed_value(request->_instance,
|
||||
request->_request._call._unique_id,
|
||||
NULL);
|
||||
request->_request._evaluate._unique_id,
|
||||
value);
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -61,11 +61,6 @@ private:
|
|||
typedef pset<P3D_instance *> 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_value *> Properties;
|
||||
Properties _properties;
|
||||
|
||||
// This nested class keeps track of active URL requests.
|
||||
class URLGetter {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -234,11 +234,11 @@ class AppRunner(DirectObject):
|
|||
def sendRequest(self, request, *args):
|
||||
self.requestFunc(self.instanceId, request, args)
|
||||
|
||||
def feedValue(self, uniqueId, value):
|
||||
""" Called by the host in response to a 'get_property' or
|
||||
'call' request. """
|
||||
def feedValue(self, uniqueId, value, success):
|
||||
""" Called by the host in response to an 'evaluate'
|
||||
request. """
|
||||
|
||||
print "feedValue(%s, %s)" % (uniqueId, value)
|
||||
print "feedValue(%s, %s, %s)" % (uniqueId, value, success)
|
||||
|
||||
def windowEvent(self, win):
|
||||
print "Got window event in runp3d"
|
||||
|
|
|
|||
Loading…
Reference in New Issue