1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Modifications to the var class to make it more javascript-compatible. Changed the handling of array types to be a shared, ref-counted array rather than being copy-by-value. Added an "undefined" type. Updated the native method invocation functions to be static (the old version used class methods) and to provide a 'this' object which may be different from the DynamicObject on which it's being invoked (this is to deal with derived classes)

This commit is contained in:
jules 2013-10-11 15:46:28 +01:00
parent 908754e0ea
commit 03ab2a2c3c
11 changed files with 243 additions and 184 deletions

View file

@ -1,2 +1,5 @@
#include "BrowserPluginCharacteristics.h"
#define JUCE_MODULE_AVAILABLE_juce_core 1
#include "BrowserPluginCharacteristics.h"

View file

@ -87,13 +87,12 @@ public:
class DemoBrowserObject : public DynamicObject
{
public:
DemoBrowserObject (JuceDemoBrowserPlugin* owner_)
: owner (owner_)
DemoBrowserObject (JuceDemoBrowserPlugin* bp) : owner (bp)
{
// Add a couple of methods to our object..
setMethod ("printText", (var::MethodFunction) &DemoBrowserObject::printText);
setMethod ("popUpMessageBox", (var::MethodFunction) &DemoBrowserObject::popUpMessageBox);
setMethod ("registerCallbackObject", (var::MethodFunction) &DemoBrowserObject::registerCallbackObject);
setMethod ("printText", printText);
setMethod ("popUpMessageBox", popUpMessageBox);
setMethod ("registerCallbackObject", registerCallbackObject);
// Add some value properties that the webpage can access
setProperty ("property1", "testing testing...");
@ -102,30 +101,33 @@ public:
//==============================================================================
// These methods are called by javascript in the webpage...
const var printText (const var* params, int numParams)
static var printText (const var::NativeFunctionArgs& args)
{
if (numParams > 0)
owner->textBox.setText (owner->textBox.getText() + "\n" + params[0].toString());
if (DemoBrowserObject* b = dynamic_cast<DemoBrowserObject*> (args.thisObject.getObject()))
if (args.numArguments > 0)
b->owner->textBox.setText (b->owner->textBox.getText() + "\n" + args.arguments[0].toString());
return "text was printed ok!";
}
const var popUpMessageBox (const var* params, int numParams)
static var popUpMessageBox (const var::NativeFunctionArgs& args)
{
if (numParams > 0)
AlertWindow::showMessageBox (AlertWindow::InfoIcon,
"A message from the webpage",
params[0].toString(),
String::empty, owner);
return var::null;
if (DemoBrowserObject* b = dynamic_cast<DemoBrowserObject*> (args.thisObject.getObject()))
if (args.numArguments > 0)
AlertWindow::showMessageBox (AlertWindow::InfoIcon,
"A message from the webpage",
args.arguments[0].toString(),
String::empty, b->owner);
return var();
}
const var registerCallbackObject (const var* params, int numParams)
static var registerCallbackObject (const var::NativeFunctionArgs& args)
{
if (numParams > 0)
owner->setJavascriptObjectFromBrowser (params[0]);
if (DemoBrowserObject* b = dynamic_cast<DemoBrowserObject*> (args.thisObject.getObject()))
if (args.numArguments > 0)
b->owner->setJavascriptObjectFromBrowser (args.arguments[0]);
return var::null;
return var();
}
//==============================================================================

View file

@ -8,7 +8,7 @@
#include "AppConfig.h"
#include "../../../modules/juce_browser_plugin/juce_browser_plugin.h"
#include "../../../modules/juce_browser_plugin_client/juce_browser_plugin.h"
#if ! DONT_SET_USING_JUCE_NAMESPACE
/* If you're not mixing JUCE with other libraries, then this will obviously save

View file

@ -1,3 +1,3 @@
#include "AppConfig.h"
#include "../../../modules/juce_browser_plugin/juce_browser_plugin.cpp"
#include "../../../modules/juce_browser_plugin_client/juce_browser_plugin.cpp"

View file

@ -229,7 +229,7 @@ public:
log ("num IDispatch wrapper objs: " + String (--numDOWID));
}
var getProperty (const Identifier& propertyName) const
var getProperty (const Identifier& propertyName) const override
{
const String nameCopy (propertyName.toString());
LPCOLESTR name = nameCopy.toUTF16();
@ -255,7 +255,7 @@ public:
return var::null;
}
bool hasProperty (const Identifier& propertyName) const
bool hasProperty (const Identifier& propertyName) const override
{
const String nameCopy (propertyName.toString());
LPCOLESTR name = nameCopy.toUTF16();
@ -263,7 +263,7 @@ public:
return source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK;
}
void setProperty (const Identifier& propertyName, const var& newValue)
void setProperty (const Identifier& propertyName, const var& newValue) override
{
const String nameCopy (propertyName.toString());
LPCOLESTR name = nameCopy.toUTF16();
@ -295,12 +295,12 @@ public:
}
}
void removeProperty (const Identifier& propertyName)
void removeProperty (const Identifier& propertyName) override
{
setProperty (propertyName, var::null);
}
bool hasMethod (const Identifier& methodName) const
bool hasMethod (const Identifier& methodName) const override
{
const String nameCopy (methodName.toString());
LPCOLESTR name = nameCopy.toUTF16();
@ -308,7 +308,7 @@ public:
return source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK;
}
var invokeMethod (const Identifier& methodName, const var* parameters, int numParameters)
var invokeMethod (Identifier methodName, const var::NativeFunctionArgs& args) override
{
var returnValue;
const String nameCopy (methodName.toString());
@ -317,14 +317,14 @@ public:
if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*) &name, 1, 0, &id) == S_OK)
{
HeapBlock <VARIANT> params;
params.calloc (numParameters + 1);
params.calloc (args.numArguments + 1);
for (int i = 0; i < numParameters; ++i)
juceVarToVariant (parameters[(numParameters - 1) - i], params[i]);
for (int i = 0; i < args.numArguments; ++i)
juceVarToVariant (args.arguments[(args.numArguments - 1) - i], params[i]);
DISPPARAMS dispParams;
zerostruct (dispParams);
dispParams.cArgs = numParameters;
dispParams.cArgs = args.numArguments;
dispParams.rgvarg = params;
EXCEPINFO excepInfo;

View file

@ -616,7 +616,7 @@ public:
DBG ("num NP wrapper objs: " + String (--numDOWNP));
}
var getProperty (const var::identifier& propertyName) const
var getProperty (const var::identifier& propertyName) const override
{
NPVariant result;
VOID_TO_NPVARIANT (result);
@ -626,7 +626,7 @@ public:
return v;
}
bool hasProperty (const var::identifier& propertyName) const
bool hasProperty (const var::identifier& propertyName) const override
{
NPVariant result;
VOID_TO_NPVARIANT (result);
@ -635,7 +635,7 @@ public:
return hasProp;
}
void setProperty (const var::identifier& propertyName, const var& newValue)
void setProperty (const var::identifier& propertyName, const var& newValue) override
{
NPVariant value;
createNPVariantFromValue (npp, value, newValue);
@ -644,40 +644,38 @@ public:
browser.releasevariantvalue (&value);
}
void removeProperty (const var::identifier& propertyName)
void removeProperty (const var::identifier& propertyName) override
{
browser.removeproperty (npp, source, getIdentifierFromString (propertyName));
}
bool hasMethod (const var::identifier& methodName) const
bool hasMethod (const var::identifier& methodName) const override
{
return browser.hasmethod (npp, source, getIdentifierFromString (methodName));
}
var invokeMethod (const var::identifier& methodName,
const var* parameters,
int numParameters)
var invokeMethod (Identifier methodName, const var::NativeFunctionArgs& args) override
{
var returnVal;
NPVariant result;
VOID_TO_NPVARIANT (result);
if (numParameters > 0)
if (args.numArguments > 0)
{
HeapBlock <NPVariant> params (numParameters);
HeapBlock<NPVariant> params (args.numArguments);
for (int i = 0; i < numParameters; ++i)
createNPVariantFromValue (npp, params[i], parameters[i]);
for (int i = 0; i < args.numArguments; ++i)
createNPVariantFromValue (npp, params[i], args.arguments[i]);
if (browser.invoke (npp, source, getIdentifierFromString (methodName),
params, numParameters, &result))
params, args.numArguments, &result))
{
returnVal = createValueFromNPVariant (npp, result);
browser.releasevariantvalue (&result);
}
for (int i = 0; i < numParameters; ++i)
for (int i = 0; i < args.numArguments; ++i)
browser.releasevariantvalue (&params[i]);
}
else
@ -705,15 +703,14 @@ public:
}
private:
NPObjectWrappingDynamicObject (NPP npp_)
: npp (npp_)
NPObjectWrappingDynamicObject (NPP n) : npp (n)
{
DBG ("num Juce wrapper objs: " + String (++numJuceWDO));
}
//==============================================================================
bool construct (const NPVariant *args, uint32_t argCount, NPVariant *result);
void invalidate() {}
void invalidate() {}
bool hasMethod (NPIdentifier name)
{
@ -742,7 +739,9 @@ private:
for (uint32_t i = 0; i < argCount; ++i)
params.params[i] = createValueFromNPVariant (npp, args[i]);
const var result (o->invokeMethod (methodName, params.params, argCount));
const var::NativeFunctionArgs argStruct = { object, params.params, (int) argCount };
const var result (o->invokeMethod (methodName, argStruct));
if (out != nullptr)
createNPVariantFromValue (npp, *out, result);

View file

@ -60,17 +60,17 @@ bool DynamicObject::hasMethod (const Identifier& methodName) const
return getProperty (methodName).isMethod();
}
var DynamicObject::invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters)
var DynamicObject::invokeMethod (Identifier method, const var::NativeFunctionArgs& args)
{
return properties [methodName].invokeMethod (this, parameters, numParameters);
if (var::NativeFunction function = properties [method].getNativeFunction())
return function (args);
return var();
}
void DynamicObject::setMethod (const Identifier& name,
var::MethodFunction methodFunction)
void DynamicObject::setMethod (Identifier name, var::NativeFunction function)
{
properties.set (name, var (methodFunction));
properties.set (name, var (function));
}
void DynamicObject::clear()

View file

@ -86,23 +86,16 @@ public:
This method is virtual to allow more dynamic invocation to used for objects
where the methods may not already be set as properies.
*/
virtual var invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters);
virtual var invokeMethod (Identifier methodName,
const var::NativeFunctionArgs& args);
/** Sets up a method.
/** Adds a method to the class.
This is basically the same as calling setProperty (methodName, (var::MethodFunction) myFunction), but
This is basically the same as calling setProperty (methodName, (var::NativeFunction) myFunction), but
helps to avoid accidentally invoking the wrong type of var constructor. It also makes
the code easier to read,
The compiler will probably force you to use an explicit cast your method to a (var::MethodFunction), e.g.
@code
setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething);
@endcode
*/
void setMethod (const Identifier& methodName,
var::MethodFunction methodFunction);
void setMethod (Identifier methodName, var::NativeFunction function);
//==============================================================================
/** Removes all properties and methods from the object. */
@ -115,6 +108,11 @@ private:
//==============================================================================
NamedValueSet properties;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// These methods have been deprecated - use var::invoke instead
virtual void invokeMethod (const Identifier&, const var*, int) {}
#endif
JUCE_LEAK_DETECTOR (DynamicObject)
};

View file

@ -35,7 +35,8 @@ enum VariantStreamMarkers
varMarker_String = 5,
varMarker_Int64 = 6,
varMarker_Array = 7,
varMarker_Binary = 8
varMarker_Binary = 8,
varMarker_Undefined = 9
};
//==============================================================================
@ -55,6 +56,7 @@ public:
virtual MemoryBlock* toBinary (const ValueUnion&) const noexcept { return nullptr; }
virtual bool isVoid() const noexcept { return false; }
virtual bool isUndefined() const noexcept { return false; }
virtual bool isInt() const noexcept { return false; }
virtual bool isInt64() const noexcept { return false; }
virtual bool isBool() const noexcept { return false; }
@ -79,10 +81,28 @@ public:
static const VariantType_Void instance;
bool isVoid() const noexcept { return true; }
bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept { return otherType.isVoid(); }
bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept { return otherType.isVoid() || otherType.isUndefined(); }
void writeToStream (const ValueUnion&, OutputStream& output) const { output.writeCompressedInt (0); }
};
//==============================================================================
class var::VariantType_Undefined : public var::VariantType
{
public:
VariantType_Undefined() noexcept {}
static const VariantType_Undefined instance;
bool isUndefined() const noexcept { return true; }
String toString (const ValueUnion&) const { return "undefined"; }
bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept { return otherType.isVoid() || otherType.isUndefined(); }
void writeToStream (const ValueUnion&, OutputStream& output) const
{
output.writeCompressedInt (1);
output.writeByte (varMarker_Undefined);
}
};
//==============================================================================
class var::VariantType_Int : public var::VariantType
{
@ -264,38 +284,56 @@ public:
};
//==============================================================================
class var::VariantType_Array : public var::VariantType
class var::VariantType_Array : public var::VariantType_Object
{
public:
VariantType_Array() noexcept {}
static const VariantType_Array instance;
void cleanUp (ValueUnion& data) const noexcept { delete data.arrayValue; }
void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.arrayValue = new Array<var> (*(source.arrayValue)); }
String toString (const ValueUnion&) const { return "[Array]"; }
ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; }
bool isArray() const noexcept { return true; }
Array<var>* toArray (const ValueUnion& data) const noexcept { return data.arrayValue; }
Array<var>* toArray (const ValueUnion& data) const noexcept
{
if (RefCountedArray* a = dynamic_cast<RefCountedArray*> (data.objectValue))
return &(a->array);
return nullptr;
}
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept
{
const Array<var>* const thisArray = toArray (data);
const Array<var>* const otherArray = otherType.toArray (otherData);
return otherArray != nullptr && *otherArray == *(data.arrayValue);
return thisArray == otherArray || (thisArray != nullptr && otherArray != nullptr && *otherArray == *thisArray);
}
void writeToStream (const ValueUnion& data, OutputStream& output) const
{
MemoryOutputStream buffer (512);
const int numItems = data.arrayValue->size();
buffer.writeCompressedInt (numItems);
if (const Array<var>* array = toArray (data))
{
MemoryOutputStream buffer (512);
const int numItems = array->size();
buffer.writeCompressedInt (numItems);
for (int i = 0; i < numItems; ++i)
data.arrayValue->getReference(i).writeToStream (buffer);
for (int i = 0; i < numItems; ++i)
array->getReference(i).writeToStream (buffer);
output.writeCompressedInt (1 + (int) buffer.getDataSize());
output.writeByte (varMarker_Array);
output << buffer;
output.writeCompressedInt (1 + (int) buffer.getDataSize());
output.writeByte (varMarker_Array);
output << buffer;
}
}
struct RefCountedArray : public ReferenceCountedObject
{
RefCountedArray (const Array<var>& a) : array (a) { incReferenceCount(); }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
RefCountedArray (Array<var>&& a) : array (static_cast<Array<var>&&> (a)) { incReferenceCount(); }
#endif
Array<var> array;
};
};
//==============================================================================
@ -351,27 +389,23 @@ public:
};
//==============================================================================
const var::VariantType_Void var::VariantType_Void::instance;
const var::VariantType_Int var::VariantType_Int::instance;
const var::VariantType_Int64 var::VariantType_Int64::instance;
const var::VariantType_Bool var::VariantType_Bool::instance;
const var::VariantType_Double var::VariantType_Double::instance;
const var::VariantType_String var::VariantType_String::instance;
const var::VariantType_Object var::VariantType_Object::instance;
const var::VariantType_Array var::VariantType_Array::instance;
const var::VariantType_Binary var::VariantType_Binary::instance;
const var::VariantType_Method var::VariantType_Method::instance;
const var::VariantType_Void var::VariantType_Void::instance;
const var::VariantType_Undefined var::VariantType_Undefined::instance;
const var::VariantType_Int var::VariantType_Int::instance;
const var::VariantType_Int64 var::VariantType_Int64::instance;
const var::VariantType_Bool var::VariantType_Bool::instance;
const var::VariantType_Double var::VariantType_Double::instance;
const var::VariantType_String var::VariantType_String::instance;
const var::VariantType_Object var::VariantType_Object::instance;
const var::VariantType_Array var::VariantType_Array::instance;
const var::VariantType_Binary var::VariantType_Binary::instance;
const var::VariantType_Method var::VariantType_Method::instance;
//==============================================================================
var::var() noexcept : type (&VariantType_Void::instance)
{
}
var::~var() noexcept
{
type->cleanUp (value);
}
var::var() noexcept : type (&VariantType_Void::instance) {}
var::var (const VariantType& t) noexcept : type (&t) {}
var::~var() noexcept { type->cleanUp (value); }
const var var::null;
@ -385,8 +419,8 @@ var::var (const int v) noexcept : type (&VariantType_Int::instance) { v
var::var (const int64 v) noexcept : type (&VariantType_Int64::instance) { value.int64Value = v; }
var::var (const bool v) noexcept : type (&VariantType_Bool::instance) { value.boolValue = v; }
var::var (const double v) noexcept : type (&VariantType_Double::instance) { value.doubleValue = v; }
var::var (MethodFunction m) noexcept : type (&VariantType_Method::instance) { value.methodValue = m; }
var::var (const Array<var>& v) : type (&VariantType_Array::instance) { value.arrayValue = new Array<var> (v); }
var::var (NativeFunction m) noexcept : type (&VariantType_Method::instance) { value.methodValue = m; }
var::var (const Array<var>& v) : type (&VariantType_Array::instance) { value.objectValue = new VariantType_Array::RefCountedArray(v); }
var::var (const String& v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
var::var (const char* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
var::var (const wchar_t* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
@ -401,9 +435,11 @@ var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::in
object->incReferenceCount();
}
var var::undefined() noexcept { return var (VariantType_Undefined::instance); }
//==============================================================================
bool var::isVoid() const noexcept { return type->isVoid(); }
bool var::isUndefined() const noexcept { return type->isUndefined(); }
bool var::isInt() const noexcept { return type->isInt(); }
bool var::isInt64() const noexcept { return type->isInt64(); }
bool var::isBool() const noexcept { return type->isBool(); }
@ -443,7 +479,7 @@ var& var::operator= (const wchar_t* const v) { type->cleanUp (value); type =
var& var::operator= (const String& v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
var& var::operator= (const Array<var>& v) { var v2 (v); swapWith (v2); return *this; }
var& var::operator= (ReferenceCountedObject* v) { var v2 (v); swapWith (v2); return *this; }
var& var::operator= (MethodFunction v) { var v2 (v); swapWith (v2); return *this; }
var& var::operator= (NativeFunction v) { var v2 (v); swapWith (v2); return *this; }
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
var::var (var&& other) noexcept
@ -469,6 +505,11 @@ var::var (MemoryBlock&& v) : type (&VariantType_Binary::instance)
value.binaryValue = new MemoryBlock (static_cast<MemoryBlock&&> (v));
}
var::var (Array<var>&& v) : type (&VariantType_Array::instance)
{
value.objectValue = new VariantType_Array::RefCountedArray (static_cast<Array<var>&&> (v));
}
var& var::operator= (String&& v)
{
type->cleanUp (value);
@ -508,7 +549,7 @@ var var::operator[] (const Identifier propertyName) const
if (DynamicObject* const o = getDynamicObject())
return o->getProperty (propertyName);
return var::null;
return var();
}
var var::operator[] (const char* const propertyName) const
@ -524,22 +565,20 @@ var var::getProperty (const Identifier propertyName, const var& defaultReturnVal
return defaultReturnValue;
}
var var::invoke (const Identifier method, const var* arguments, int numArguments) const
var::NativeFunction var::getNativeFunction() const
{
if (DynamicObject* const o = getDynamicObject())
return o->invokeMethod (method, arguments, numArguments);
return var::null;
return isMethod() ? value.methodValue : nullptr;
}
var var::invokeMethod (DynamicObject* const target, const var* const arguments, const int numArguments) const
var var::invoke (Identifier method, const var* arguments, int numArguments) const
{
jassert (target != nullptr);
if (DynamicObject* const o = getDynamicObject())
{
const var::NativeFunctionArgs args = { *this, arguments, numArguments };
return o->invokeMethod (method, args);
}
if (isMethod())
return (target->*(value.methodValue)) (arguments, numArguments);
return var::null;
return var();
}
var var::call (const Identifier method) const
@ -609,21 +648,15 @@ var& var::operator[] (int arrayIndex)
Array<var>* var::convertToArray()
{
Array<var>* array = getArray();
if (Array<var>* array = getArray())
return array;
if (array == nullptr)
{
const Array<var> tempVar;
var v (tempVar);
array = v.value.arrayValue;
Array<var> tempVar;
if (! isVoid())
tempVar.add (*this);
if (! isVoid())
array->add (*this);
swapWith (v);
}
return array;
*this = tempVar;
return getArray();
}
void var::append (const var& n)
@ -710,5 +743,5 @@ var var::readFromStream (InputStream& input)
}
}
return var::null;
return var();
}

View file

@ -47,7 +47,17 @@ class JUCE_API var
{
public:
//==============================================================================
typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);
/** This structure is passed to a NativeFunction callback, and contains invocation
details about the function's arguments and context.
*/
struct NativeFunctionArgs
{
const var& thisObject;
const var* arguments;
int numArguments;
};
typedef var (*NativeFunction) (const NativeFunctionArgs&);
typedef Identifier identifier;
//==============================================================================
@ -70,7 +80,7 @@ public:
var (const String& value);
var (const Array<var>& value);
var (ReferenceCountedObject* object);
var (MethodFunction method) noexcept;
var (NativeFunction method) noexcept;
var (const void* binaryData, size_t dataSize);
var (const MemoryBlock& binaryData);
@ -84,18 +94,22 @@ public:
var& operator= (const String& value);
var& operator= (const Array<var>& value);
var& operator= (ReferenceCountedObject* object);
var& operator= (MethodFunction method);
var& operator= (NativeFunction method);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
var (var&& other) noexcept;
var (String&& value);
var (MemoryBlock&& binaryData);
var (Array<var>&& value);
var& operator= (var&& other) noexcept;
var& operator= (String&& value);
#endif
void swapWith (var& other) noexcept;
/** Returns a var object that can be used where you need the javascript "undefined" value. */
static var undefined() noexcept;
//==============================================================================
operator int() const noexcept;
operator int64() const noexcept;
@ -126,6 +140,7 @@ public:
//==============================================================================
bool isVoid() const noexcept;
bool isUndefined() const noexcept;
bool isInt() const noexcept;
bool isInt64() const noexcept;
bool isBool() const noexcept;
@ -217,27 +232,29 @@ public:
//==============================================================================
/** If this variant is an object, this returns one of its properties. */
var operator[] (const Identifier propertyName) const;
var operator[] (Identifier propertyName) const;
/** If this variant is an object, this returns one of its properties. */
var operator[] (const char* propertyName) const;
/** If this variant is an object, this returns one of its properties, or a default
fallback value if the property is not set. */
var getProperty (const Identifier propertyName, const var& defaultReturnValue) const;
var getProperty (Identifier propertyName, const var& defaultReturnValue) const;
/** If this variant is an object, this invokes one of its methods with no arguments. */
var call (const Identifier method) const;
/** If this variant is an object, this invokes one of its methods with one argument. */
var call (const Identifier method, const var& arg1) const;
/** If this variant is an object, this invokes one of its methods with 2 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2) const;
/** If this variant is an object, this invokes one of its methods with 3 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2, const var& arg3);
/** If this variant is an object, this invokes one of its methods with 4 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
/** If this variant is an object, this invokes one of its methods with 5 arguments. */
var call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
/** If this variant is an object, this invokes one of its methods with a list of arguments. */
var invoke (const Identifier method, const var* arguments, int numArguments) const;
/** Invokes a named method call with no arguments. */
var call (Identifier method) const;
/** Invokes a named method call with one argument. */
var call (Identifier method, const var& arg1) const;
/** Invokes a named method call with 2 arguments. */
var call (Identifier method, const var& arg1, const var& arg2) const;
/** Invokes a named method call with 3 arguments. */
var call (Identifier method, const var& arg1, const var& arg2, const var& arg3);
/** Invokes a named method call with 4 arguments. */
var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
/** Invokes a named method call with 5 arguments. */
var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
/** Invokes a named method call with a list of arguments. */
var invoke (Identifier method, const var* arguments, int numArguments) const;
/** If this object is a method, this returns the function pointer. */
NativeFunction getNativeFunction() const;
//==============================================================================
/** Writes a binary representation of this value to a stream.
@ -255,17 +272,18 @@ public:
private:
//==============================================================================
class VariantType; friend class VariantType;
class VariantType_Void; friend class VariantType_Void;
class VariantType_Int; friend class VariantType_Int;
class VariantType_Int64; friend class VariantType_Int64;
class VariantType_Double; friend class VariantType_Double;
class VariantType_Bool; friend class VariantType_Bool;
class VariantType_String; friend class VariantType_String;
class VariantType_Object; friend class VariantType_Object;
class VariantType_Array; friend class VariantType_Array;
class VariantType_Binary; friend class VariantType_Binary;
class VariantType_Method; friend class VariantType_Method;
class VariantType; friend class VariantType;
class VariantType_Void; friend class VariantType_Void;
class VariantType_Undefined; friend class VariantType_Undefined;
class VariantType_Int; friend class VariantType_Int;
class VariantType_Int64; friend class VariantType_Int64;
class VariantType_Double; friend class VariantType_Double;
class VariantType_Bool; friend class VariantType_Bool;
class VariantType_String; friend class VariantType_String;
class VariantType_Object; friend class VariantType_Object;
class VariantType_Array; friend class VariantType_Array;
class VariantType_Binary; friend class VariantType_Binary;
class VariantType_Method; friend class VariantType_Method;
union ValueUnion
{
@ -275,17 +293,15 @@ private:
double doubleValue;
char stringValue [sizeof (String)];
ReferenceCountedObject* objectValue;
Array<var>* arrayValue;
MemoryBlock* binaryValue;
MethodFunction methodValue;
NativeFunction methodValue;
};
const VariantType* type;
ValueUnion value;
Array<var>* convertToArray();
friend class DynamicObject;
var invokeMethod (DynamicObject*, const var*, int) const;
var (const VariantType&) noexcept;
};
/** Compares the values of two var objects, using the var::equals() comparison. */

View file

@ -338,6 +338,10 @@ public:
{
out << "null";
}
else if (v.isUndefined())
{
out << "undefined";
}
else if (v.isBool())
{
out << (static_cast<bool> (v) ? "true" : "false");
@ -421,29 +425,33 @@ public:
const int indentLevel, const bool allOnOneLine)
{
out << '[';
if (! allOnOneLine)
out << newLine;
for (int i = 0; i < array.size(); ++i)
if (array.size() > 0)
{
if (! allOnOneLine)
writeSpaces (out, indentLevel + indentSize);
write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine);
if (i < array.size() - 1)
{
if (allOnOneLine)
out << ", ";
else
out << ',' << newLine;
}
else if (! allOnOneLine)
out << newLine;
}
if (! allOnOneLine)
writeSpaces (out, indentLevel);
for (int i = 0; i < array.size(); ++i)
{
if (! allOnOneLine)
writeSpaces (out, indentLevel + indentSize);
write (out, array.getReference(i), indentLevel + indentSize, allOnOneLine);
if (i < array.size() - 1)
{
if (allOnOneLine)
out << ", ";
else
out << ',' << newLine;
}
else if (! allOnOneLine)
out << newLine;
}
if (! allOnOneLine)
writeSpaces (out, indentLevel);
}
out << ']';
}