| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file ppBrowserObject.cxx
- * @author drose
- * @date 2009-07-05
- */
- #include "ppBrowserObject.h"
- #include "ppInstance.h"
- #include <sstream>
- #include <string.h> // strncpy
- // The following functions are C-style wrappers around the above
- // PPBrowserObject methods; they are defined to allow us to create the C-style
- // P3D_class_definition method table to store in the P3D_object structure.
- static void
- object_finish(P3D_object *object) {
- delete ((PPBrowserObject *)object);
- }
- static int
- 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(P3D_object *object, const char *property) {
- return ((const PPBrowserObject *)object)->get_property(property);
- }
- static bool
- object_set_property(P3D_object *object, const char *property,
- bool needs_response, P3D_object *value) {
- return ((PPBrowserObject *)object)->set_property(property, needs_response, value);
- }
- static P3D_object *
- object_call(P3D_object *object, const char *method_name,
- bool needs_response,
- P3D_object *params[], int num_params) {
- if (method_name == nullptr) {
- method_name = "";
- }
- P3D_object *response = ((const PPBrowserObject *)object)->call(method_name, params, num_params);
- if (!needs_response) {
- // No response was expected. Throw away the response we received, so we
- // can be consistent with defined semantics.
- P3D_OBJECT_XDECREF(response);
- response = nullptr;
- }
- return response;
- }
- static P3D_object *
- object_eval(P3D_object *object, const char *expression) {
- return ((const PPBrowserObject *)object)->eval(expression);
- }
- P3D_class_definition *PPBrowserObject::_browser_object_class;
- /**
- *
- */
- PPBrowserObject::
- PPBrowserObject(PPInstance *inst, NPObject *npobj) :
- _instance(inst),
- _npobj(npobj)
- {
- _class = get_class_definition();
- _ref_count = 1;
- browser->retainobject(_npobj);
- }
- /**
- *
- */
- PPBrowserObject::
- PPBrowserObject(const PPBrowserObject ©) :
- _instance(copy._instance),
- _npobj(copy._npobj)
- {
- _class = get_class_definition();
- _ref_count = 1;
- browser->retainobject(_npobj);
- }
- /**
- *
- */
- PPBrowserObject::
- ~PPBrowserObject() {
- assert(_ref_count == 0);
- browser->releaseobject(_npobj);
- }
- /**
- * Returns a user-friendly representation of the object, similar to
- * get_string(), above.
- */
- int PPBrowserObject::
- get_repr(char *buffer, int buffer_length) const {
- ostringstream strm;
- strm << "NPObject " << _npobj;
- string result = strm.str();
- strncpy(buffer, result.c_str(), buffer_length);
- return (int)result.size();
- }
- /**
- * Returns the named property element in the object. The return value is a
- * freshly-allocated PPBrowserObject object that must be deleted by the
- * caller, or NULL on error.
- */
- P3D_object *PPBrowserObject::
- get_property(const string &property) const {
- NPIdentifier property_name = browser->getstringidentifier(property.c_str());
- if (!browser->hasproperty(_instance->get_npp_instance(), _npobj,
- property_name)) {
- // No such property.
- return nullptr;
- }
- NPVariant result;
- if (!browser->getproperty(_instance->get_npp_instance(), _npobj,
- property_name, &result)) {
- // Failed to retrieve property.
- return nullptr;
- }
- P3D_object *object = _instance->variant_to_p3dobj(&result);
- browser->releasevariantvalue(&result);
- return object;
- }
- /**
- * Modifies (or deletes, if value is NULL) the named property element in the
- * object. Returns true on success, false on failure.
- */
- bool PPBrowserObject::
- set_property(const string &property, bool needs_response, P3D_object *value) {
- NPIdentifier property_name = browser->getstringidentifier(property.c_str());
- bool result;
- if (value != nullptr) {
- // Set the property.
- NPVariant npvalue;
- _instance->p3dobj_to_variant(&npvalue, value);
- result = browser->setproperty(_instance->get_npp_instance(), _npobj,
- property_name, &npvalue);
- browser->releasevariantvalue(&npvalue);
- } else {
- // Delete the property.
- result = browser->removeproperty(_instance->get_npp_instance(), _npobj,
- property_name);
- }
- return result;
- }
- /**
- * Invokes the named method on the object, passing the indicated parameters.
- * If the method name is empty, invokes the object itself. Returns the return
- * value on success, NULL on error.
- */
- P3D_object *PPBrowserObject::
- call(const string &method_name, P3D_object *params[], int num_params) const {
- // First, convert all of the parameters.
- NPVariant *npparams = new NPVariant[num_params];
- for (int i = 0; i < num_params; ++i) {
- _instance->p3dobj_to_variant(&npparams[i], params[i]);
- }
- NPVariant result;
- if (method_name.empty()) {
- // Call the default method.
- if (!browser->invokeDefault(_instance->get_npp_instance(), _npobj,
- npparams, num_params, &result)) {
- // Failed to invoke.
- delete[] npparams;
- return nullptr;
- }
- } else {
- // Call the named method.
- NPIdentifier method_id = browser->getstringidentifier(method_name.c_str());
- if (!browser->invoke(_instance->get_npp_instance(), _npobj, method_id,
- npparams, num_params, &result)) {
- // Failed to invoke.
- delete[] npparams;
- return nullptr;
- }
- }
- delete[] npparams;
- P3D_object *object = _instance->variant_to_p3dobj(&result);
- browser->releasevariantvalue(&result);
- return object;
- }
- /**
- * Evaluates the indicated JavaScript expression in the context of the object.
- */
- P3D_object *PPBrowserObject::
- eval(const string &expression) const {
- NPString npexpr = { expression.c_str(), (uint32_t)expression.length() };
- NPVariant result;
- if (!browser->evaluate(_instance->get_npp_instance(), _npobj,
- &npexpr, &result)) {
- // Failed to eval.
- return nullptr;
- }
- P3D_object *object = _instance->variant_to_p3dobj(&result);
- browser->releasevariantvalue(&result);
- return object;
- }
- /**
- * Should be called when the core API is unloaded, and the associated class
- * definition object is therefore invalidated.
- */
- void PPBrowserObject::
- clear_class_definition() {
- _browser_object_class = nullptr;
- }
- /**
- * Returns a pointer to the P3D_class_definition object that lists all of the
- * C-style method pointers for this class object.
- */
- P3D_class_definition *PPBrowserObject::
- get_class_definition() {
- if (_browser_object_class == nullptr) {
- // Create a default class_definition object, and fill in the appropriate
- // pointers.
- _browser_object_class = P3D_make_class_definition_ptr();
- _browser_object_class->_finish = &object_finish;
- _browser_object_class->_get_repr = &object_get_repr;
- _browser_object_class->_get_property = &object_get_property;
- _browser_object_class->_set_property = &object_set_property;
- _browser_object_class->_call = &object_call;
- _browser_object_class->_eval = &object_eval;
- }
- return _browser_object_class;
- }
|