more inbound scripting

This commit is contained in:
David Rose 2009-07-04 21:10:45 +00:00
parent ed037be160
commit 165a57a38a
2 changed files with 151 additions and 12 deletions

View File

@ -45,7 +45,7 @@ make_new(PPInstance *inst, P3D_object *p3d_object) {
NPObject *npobj =
browser->createobject(inst->get_npp_instance(), &_object_class);
PPObject *ppobj = (PPObject *)npobj;
ppobj->construct(p3d_object);
ppobj->construct(inst, p3d_object);
return ppobj;
}
@ -53,7 +53,8 @@ make_new(PPInstance *inst, P3D_object *p3d_object) {
// Function: PPObject::set_p3d_object
// Access: Public
// Description: Changes the p3d_object this PPObject maps to. The
// previous object, if any, is deleted.
// previous object, if any, is deleted. Ownership of
// the new object is passed to the PPObject.
////////////////////////////////////////////////////////////////////
void PPObject::
set_p3d_object(P3D_object *p3d_object) {
@ -74,8 +75,9 @@ set_p3d_object(P3D_object *p3d_object) {
// following NPN_CreateObject().
////////////////////////////////////////////////////////////////////
void PPObject::
construct(P3D_object *p3d_object) {
construct(PPInstance *inst, P3D_object *p3d_object) {
logfile << "construct: " << this << "\n" << flush;
_instance = inst;
_p3d_object = p3d_object;
}
@ -87,6 +89,7 @@ construct(P3D_object *p3d_object) {
void PPObject::
invalidate() {
logfile << "invalidate: " << this << "\n" << flush;
_instance = NULL;
set_p3d_object(NULL);
}
@ -98,7 +101,8 @@ invalidate() {
////////////////////////////////////////////////////////////////////
bool PPObject::
has_method(NPIdentifier name) {
logfile << "has_method: " << this << "\n" << flush;
string property_name = identifier_to_string(name);
logfile << "has_method: " << this << ", " << property_name << "\n" << flush;
return false;
}
@ -138,8 +142,14 @@ invoke_default(const NPVariant *args, uint32_t argCount,
////////////////////////////////////////////////////////////////////
bool PPObject::
has_property(NPIdentifier name) {
logfile << "has_property: " << this << "\n" << flush;
return false;
string property_name = identifier_to_string(name);
logfile << "has_property: " << this << ", " << property_name << "\n" << flush;
// If we say we don't have a given property, then set_property()
// will never be called. So we always say we *do* have any
// particular property, whether we currently have it right now or
// not (since we *could* have it if you call set_property()).
return true;
}
////////////////////////////////////////////////////////////////////
@ -151,8 +161,23 @@ has_property(NPIdentifier name) {
////////////////////////////////////////////////////////////////////
bool PPObject::
get_property(NPIdentifier name, NPVariant *result) {
logfile << "get_property: " << this << "\n" << flush;
return false;
string property_name = identifier_to_string(name);
logfile << "get_property: " << this << ", " << property_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
}
P3D_object *value = P3D_OBJECT_GET_PROPERTY(_p3d_object, property_name.c_str());
if (value == NULL) {
// No such property.
return false;
}
// We have the property, and its value is stored in value.
object_to_variant(result, value);
P3D_OBJECT_FINISH(value);
return true;
}
////////////////////////////////////////////////////////////////////
@ -163,8 +188,16 @@ get_property(NPIdentifier name, NPVariant *result) {
////////////////////////////////////////////////////////////////////
bool PPObject::
set_property(NPIdentifier name, const NPVariant *value) {
logfile << "set_property: " << this << "\n" << flush;
return false;
string property_name = identifier_to_string(name);
logfile << "set_property: " << this << ", " << property_name << "\n" << flush;
if (_p3d_object == NULL) {
// Not powered up yet.
return false;
}
P3D_object *object = variant_to_object(value);
bool result = P3D_OBJECT_SET_PROPERTY(_p3d_object, property_name.c_str(), object);
return result;
}
////////////////////////////////////////////////////////////////////
@ -197,6 +230,101 @@ enumerate(NPIdentifier **value, uint32_t *count) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PPObject::identifier_to_string
// Access: Private, Static
// Description: Gets the string equivalent of the indicated
// identifier.
////////////////////////////////////////////////////////////////////
string PPObject::
identifier_to_string(NPIdentifier ident) {
if (browser->identifierisstring(ident)) {
NPUTF8 *result = browser->utf8fromidentifier(ident);
if (result != NULL) {
string strval(result);
browser->memfree(result);
return strval;
}
}
return string();
}
////////////////////////////////////////////////////////////////////
// Function: PPObject::object_to_variant
// Access: Private
// Description: Converts the indicated P3D_object to the equivalent
// NPVariant, and stores it in result.
////////////////////////////////////////////////////////////////////
void PPObject::
object_to_variant(NPVariant *result, const P3D_object *object) {
switch (P3D_OBJECT_GET_TYPE(object)) {
case P3D_OT_none:
VOID_TO_NPVARIANT(*result);
break;
case P3D_OT_bool:
BOOLEAN_TO_NPVARIANT(P3D_OBJECT_GET_BOOL(object), *result);
break;
case P3D_OT_int:
INT32_TO_NPVARIANT(P3D_OBJECT_GET_INT(object), *result);
break;
case P3D_OT_float:
DOUBLE_TO_NPVARIANT(P3D_OBJECT_GET_FLOAT(object), *result);
break;
case P3D_OT_string:
{
int size = P3D_OBJECT_GET_STRING(object, NULL, 0);
char *buffer = (char *)browser->memalloc(size);
P3D_OBJECT_GET_STRING(object, buffer, size);
STRINGN_TO_NPVARIANT(buffer, size, *result);
}
break;
case P3D_OT_list:
case P3D_OT_object:
{
PPObject *ppobj = PPObject::make_new(_instance, P3D_OBJECT_COPY(object));
OBJECT_TO_NPVARIANT(ppobj, *result);
}
break;
}
}
////////////////////////////////////////////////////////////////////
// Function: PPObject::variant_to_object
// Access: Private
// Description: Converts the indicated NPVariant to the equivalent
// P3D_object, and returns it (newly-allocated). The
// caller is responsible for freeing the returned object
// later.
////////////////////////////////////////////////////////////////////
P3D_object *PPObject::
variant_to_object(const NPVariant *variant) {
if (NPVARIANT_IS_VOID(*variant) ||
NPVARIANT_IS_NULL(*variant)) {
return P3D_new_none_object();
} else if (NPVARIANT_IS_BOOLEAN(*variant)) {
return P3D_new_bool_object(NPVARIANT_TO_BOOLEAN(*variant));
} else if (NPVARIANT_IS_INT32(*variant)) {
return P3D_new_int_object(NPVARIANT_TO_INT32(*variant));
} else if (NPVARIANT_IS_DOUBLE(*variant)) {
return P3D_new_float_object(NPVARIANT_TO_DOUBLE(*variant));
} else if (NPVARIANT_IS_STRING(*variant)) {
NPString str = NPVARIANT_TO_STRING(*variant);
return P3D_new_string_object(str.utf8characters, str.utf8length);
} else if (NPVARIANT_IS_OBJECT(*variant)) {
// TODO.
return P3D_new_none_object();
}
// Hmm, none of the above?
return P3D_new_none_object();
}
// The remaining function bodies are the C-style function wrappers
// that are called directly by NPAPI, and which redirect into the
@ -224,6 +352,7 @@ NPAllocate(NPP npp, NPClass *aClass) {
void PPObject::
NPDeallocate(NPObject *npobj) {
logfile << "NPDeallocate: " << npobj << "\n" << flush;
((PPObject *)npobj)->invalidate();
free(npobj);
}
@ -235,7 +364,10 @@ NPDeallocate(NPObject *npobj) {
void PPObject::
NPInvalidate(NPObject *npobj) {
logfile << "NPInvalidate: " << npobj << "\n" << flush;
((PPObject *)npobj)->invalidate();
// It turns out that this method isn't actually called by Safari's
// implementation of NPAPI, so we'll move the actual destructor call
// into NPDeallocate, above.
}
////////////////////////////////////////////////////////////////////

View File

@ -31,7 +31,7 @@ public:
void set_p3d_object(P3D_object *p3d_object);
private:
void construct(P3D_object *p3d_object);
void construct(PPInstance *inst, P3D_object *p3d_object);
void invalidate();
bool has_method(NPIdentifier name);
@ -48,6 +48,12 @@ private:
bool remove_property(NPIdentifier name);
bool enumerate(NPIdentifier **value, uint32_t *count);
private:
static string identifier_to_string(NPIdentifier ident);
void object_to_variant(NPVariant *result, const P3D_object *object);
P3D_object *variant_to_object(const NPVariant *variant);
private:
static NPObject *NPAllocate(NPP npp, NPClass *aClass);
static void NPDeallocate(NPObject *npobj);
@ -75,6 +81,7 @@ private:
NPVariant *result);
private:
PPInstance *_instance;
P3D_object *_p3d_object;
static NPClass _object_class;