mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-03 03:30:06 +00:00
ALSA fix. Removed some win32 compile warnings. Refactored Variant class internally.
This commit is contained in:
parent
e502d753d7
commit
366c8fb7e2
10 changed files with 633 additions and 456 deletions
|
|
@ -32,71 +32,260 @@ BEGIN_JUCE_NAMESPACE
|
|||
|
||||
|
||||
//==============================================================================
|
||||
var::var() throw()
|
||||
: type (voidType)
|
||||
class var::VariantType
|
||||
{
|
||||
public:
|
||||
VariantType() {}
|
||||
virtual ~VariantType() {}
|
||||
|
||||
virtual int toInt (const ValueUnion&) const { return 0; }
|
||||
virtual double toDouble (const ValueUnion&) const { return 0; }
|
||||
virtual float toFloat (const ValueUnion&) const { return 0; }
|
||||
virtual const String toString (const ValueUnion&) const { return String::empty; }
|
||||
virtual bool toBool (const ValueUnion&) const { return false; }
|
||||
virtual DynamicObject* toObject (const ValueUnion&) const { return 0; }
|
||||
|
||||
virtual bool isVoid() const throw() { return false; }
|
||||
virtual bool isInt() const throw() { return false; }
|
||||
virtual bool isBool() const throw() { return false; }
|
||||
virtual bool isDouble() const throw() { return false; }
|
||||
virtual bool isString() const throw() { return false; }
|
||||
virtual bool isObject() const throw() { return false; }
|
||||
virtual bool isMethod() const throw() { return false; }
|
||||
|
||||
virtual void cleanUp (ValueUnion&) const throw() {}
|
||||
virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; }
|
||||
virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() = 0;
|
||||
virtual void writeToStream (const ValueUnion& data, OutputStream& output) const = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_Void : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_Void* getInstance() { static const VariantType_Void i; return &i; }
|
||||
|
||||
bool isVoid() const throw() { return true; }
|
||||
bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const throw() { return otherType.isVoid(); }
|
||||
void writeToStream (const ValueUnion&, OutputStream& output) const { output.writeCompressedInt (0); }
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_Int : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_Int* getInstance() { static const VariantType_Int i; return &i; }
|
||||
|
||||
int toInt (const ValueUnion& data) const { return data.intValue; };
|
||||
double toDouble (const ValueUnion& data) const { return (double) data.intValue; }
|
||||
float toFloat (const ValueUnion& data) const { return (float) data.intValue; }
|
||||
const String toString (const ValueUnion& data) const { return String (data.intValue); }
|
||||
bool toBool (const ValueUnion& data) const { return data.intValue != 0; }
|
||||
|
||||
bool isInt() const throw() { return true; }
|
||||
|
||||
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw()
|
||||
{
|
||||
return otherType.toInt (otherData) == data.intValue;
|
||||
}
|
||||
|
||||
void writeToStream (const ValueUnion& data, OutputStream& output) const
|
||||
{
|
||||
output.writeCompressedInt (5);
|
||||
output.writeByte (1);
|
||||
output.writeInt (data.intValue);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_Double : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_Double* getInstance() { static const VariantType_Double i; return &i; }
|
||||
|
||||
int toInt (const ValueUnion& data) const { return (int) data.doubleValue; };
|
||||
double toDouble (const ValueUnion& data) const { return data.doubleValue; }
|
||||
float toFloat (const ValueUnion& data) const { return (float) data.doubleValue; }
|
||||
const String toString (const ValueUnion& data) const { return String (data.doubleValue); }
|
||||
bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; }
|
||||
|
||||
bool isDouble() const throw() { return true; }
|
||||
|
||||
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw()
|
||||
{
|
||||
return otherType.toDouble (otherData) == data.doubleValue;
|
||||
}
|
||||
|
||||
void writeToStream (const ValueUnion& data, OutputStream& output) const
|
||||
{
|
||||
output.writeCompressedInt (9);
|
||||
output.writeByte (4);
|
||||
output.writeDouble (data.doubleValue);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_Bool : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_Bool* getInstance() { static const VariantType_Bool i; return &i; }
|
||||
|
||||
int toInt (const ValueUnion& data) const { return data.boolValue ? 1 : 0; };
|
||||
double toDouble (const ValueUnion& data) const { return data.boolValue ? 1.0 : 0.0; }
|
||||
float toFloat (const ValueUnion& data) const { return data.boolValue ? 1.0f : 0.0f; }
|
||||
const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); }
|
||||
bool toBool (const ValueUnion& data) const { return data.boolValue; }
|
||||
|
||||
bool isBool() const throw() { return true; }
|
||||
|
||||
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw()
|
||||
{
|
||||
return otherType.toBool (otherData) == data.boolValue;
|
||||
}
|
||||
|
||||
void writeToStream (const ValueUnion& data, OutputStream& output) const
|
||||
{
|
||||
output.writeCompressedInt (1);
|
||||
output.writeByte (data.boolValue ? 2 : 3);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_String : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_String* getInstance() { static const VariantType_String i; return &i; }
|
||||
|
||||
void cleanUp (ValueUnion& data) const throw() { delete data.stringValue; }
|
||||
void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); }
|
||||
|
||||
int toInt (const ValueUnion& data) const { return data.stringValue->getIntValue(); };
|
||||
double toDouble (const ValueUnion& data) const { return data.stringValue->getDoubleValue(); }
|
||||
float toFloat (const ValueUnion& data) const { return data.stringValue->getFloatValue(); }
|
||||
const String toString (const ValueUnion& data) const { return *data.stringValue; }
|
||||
bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0
|
||||
|| data.stringValue->trim().equalsIgnoreCase ("true")
|
||||
|| data.stringValue->trim().equalsIgnoreCase ("yes"); }
|
||||
|
||||
bool isString() const throw() { return true; }
|
||||
|
||||
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw()
|
||||
{
|
||||
return otherType.toString (otherData) == *data.stringValue;
|
||||
}
|
||||
|
||||
void writeToStream (const ValueUnion& data, OutputStream& output) const
|
||||
{
|
||||
const int len = data.stringValue->getNumBytesAsUTF8() + 1;
|
||||
output.writeCompressedInt (len + 1);
|
||||
output.writeByte (5);
|
||||
HeapBlock<char> temp (len);
|
||||
data.stringValue->copyToUTF8 (temp, len);
|
||||
output.write (temp, len);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_Object : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_Object* getInstance() { static const VariantType_Object i; return &i; }
|
||||
|
||||
void cleanUp (ValueUnion& data) const throw() { if (data.objectValue != 0) data.objectValue->decReferenceCount(); }
|
||||
void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.objectValue = source.objectValue; if (dest.objectValue != 0) dest.objectValue->incReferenceCount(); }
|
||||
|
||||
const String toString (const ValueUnion& data) const { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); }
|
||||
bool toBool (const ValueUnion& data) const { return data.objectValue != 0; }
|
||||
DynamicObject* toObject (const ValueUnion& data) const { return data.objectValue; }
|
||||
|
||||
bool isObject() const throw() { return true; }
|
||||
|
||||
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw()
|
||||
{
|
||||
return otherType.toObject (otherData) == data.objectValue;
|
||||
}
|
||||
|
||||
void writeToStream (const ValueUnion&, OutputStream& output) const
|
||||
{
|
||||
jassertfalse; // Can't write an object to a stream!
|
||||
output.writeCompressedInt (0);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class var::VariantType_Method : public var::VariantType
|
||||
{
|
||||
public:
|
||||
static const VariantType_Method* getInstance() { static const VariantType_Method i; return &i; }
|
||||
|
||||
const String toString (const ValueUnion&) const { return "Method"; }
|
||||
bool toBool (const ValueUnion& data) const { return data.methodValue != 0; }
|
||||
|
||||
bool isMethod() const throw() { return true; }
|
||||
|
||||
bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw()
|
||||
{
|
||||
return otherType.isMethod() && otherData.methodValue == data.methodValue;
|
||||
}
|
||||
|
||||
void writeToStream (const ValueUnion&, OutputStream& output) const
|
||||
{
|
||||
jassertfalse; // Can't write a method to a stream!
|
||||
output.writeCompressedInt (0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
var::var() throw()
|
||||
: type (VariantType_Void::getInstance())
|
||||
{
|
||||
value.doubleValue = 0;
|
||||
}
|
||||
|
||||
var::~var() throw()
|
||||
{
|
||||
if (type == stringType)
|
||||
delete value.stringValue;
|
||||
else if (type == objectType && value.objectValue != 0)
|
||||
value.objectValue->decReferenceCount();
|
||||
type->cleanUp (value);
|
||||
}
|
||||
|
||||
const var var::null;
|
||||
|
||||
//==============================================================================
|
||||
var::var (const var& valueToCopy)
|
||||
: type (valueToCopy.type),
|
||||
value (valueToCopy.value)
|
||||
var::var (const var& valueToCopy) : type (valueToCopy.type)
|
||||
{
|
||||
if (type == stringType)
|
||||
value.stringValue = new String (*(value.stringValue));
|
||||
else if (type == objectType && value.objectValue != 0)
|
||||
value.objectValue->incReferenceCount();
|
||||
type->createCopy (value, valueToCopy.value);
|
||||
}
|
||||
|
||||
var::var (const int value_) throw()
|
||||
: type (intType)
|
||||
var::var (const int value_) throw() : type (VariantType_Int::getInstance())
|
||||
{
|
||||
value.intValue = value_;
|
||||
}
|
||||
|
||||
var::var (const bool value_) throw()
|
||||
: type (boolType)
|
||||
var::var (const bool value_) throw() : type (VariantType_Bool::getInstance())
|
||||
{
|
||||
value.boolValue = value_;
|
||||
}
|
||||
|
||||
var::var (const double value_) throw()
|
||||
: type (doubleType)
|
||||
var::var (const double value_) throw() : type (VariantType_Double::getInstance())
|
||||
{
|
||||
value.doubleValue = value_;
|
||||
}
|
||||
|
||||
var::var (const String& value_)
|
||||
: type (stringType)
|
||||
var::var (const String& value_) : type (VariantType_String::getInstance())
|
||||
{
|
||||
value.stringValue = new String (value_);
|
||||
}
|
||||
|
||||
var::var (const char* const value_)
|
||||
: type (stringType)
|
||||
var::var (const char* const value_) : type (VariantType_String::getInstance())
|
||||
{
|
||||
value.stringValue = new String (value_);
|
||||
}
|
||||
|
||||
var::var (const juce_wchar* const value_)
|
||||
: type (stringType)
|
||||
var::var (const juce_wchar* const value_) : type (VariantType_String::getInstance())
|
||||
{
|
||||
value.stringValue = new String (value_);
|
||||
}
|
||||
|
||||
var::var (DynamicObject* const object)
|
||||
: type (objectType)
|
||||
var::var (DynamicObject* const object) : type (VariantType_Object::getInstance())
|
||||
{
|
||||
value.objectValue = object;
|
||||
|
||||
|
|
@ -104,12 +293,28 @@ var::var (DynamicObject* const object)
|
|||
object->incReferenceCount();
|
||||
}
|
||||
|
||||
var::var (MethodFunction method_) throw()
|
||||
: type (methodType)
|
||||
var::var (MethodFunction method_) throw() : type (VariantType_Method::getInstance())
|
||||
{
|
||||
value.methodValue = method_;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool var::isVoid() const throw() { return type->isVoid(); }
|
||||
bool var::isInt() const throw() { return type->isInt(); }
|
||||
bool var::isBool() const throw() { return type->isBool(); }
|
||||
bool var::isDouble() const throw() { return type->isDouble(); }
|
||||
bool var::isString() const throw() { return type->isString(); }
|
||||
bool var::isObject() const throw() { return type->isObject(); }
|
||||
bool var::isMethod() const throw() { return type->isMethod(); }
|
||||
|
||||
var::operator int() const { return type->toInt (value); }
|
||||
var::operator bool() const { return type->toBool (value); }
|
||||
var::operator float() const { return type->toFloat (value); }
|
||||
var::operator double() const { return type->toDouble (value); }
|
||||
const String var::toString() const { return type->toString (value); }
|
||||
var::operator const String() const { return type->toString (value); }
|
||||
DynamicObject* var::getObject() const { return type->toObject (value); }
|
||||
|
||||
//==============================================================================
|
||||
void var::swapWith (var& other) throw()
|
||||
{
|
||||
|
|
@ -117,115 +322,20 @@ void var::swapWith (var& other) throw()
|
|||
swapVariables (value, other.value);
|
||||
}
|
||||
|
||||
var& var::operator= (const var& value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (int value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (bool value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (double value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (const char* value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (const juce_wchar* value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (const String& value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (DynamicObject* value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
var& var::operator= (MethodFunction value_) { var newValue (value_); swapWith (newValue); return *this; }
|
||||
|
||||
//==============================================================================
|
||||
var::operator int() const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case voidType: break;
|
||||
case intType: return value.intValue;
|
||||
case boolType: return value.boolValue ? 1 : 0;
|
||||
case doubleType: return static_cast <int> (value.doubleValue);
|
||||
case stringType: return value.stringValue->getIntValue();
|
||||
case objectType: break;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var::operator bool() const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case voidType: break;
|
||||
case intType: return value.intValue != 0;
|
||||
case boolType: return value.boolValue;
|
||||
case doubleType: return value.doubleValue != 0;
|
||||
case stringType: return value.stringValue->getIntValue() != 0
|
||||
|| value.stringValue->trim().equalsIgnoreCase ("true")
|
||||
|| value.stringValue->trim().equalsIgnoreCase ("yes");
|
||||
case objectType: return value.objectValue != 0;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var::operator float() const
|
||||
{
|
||||
return (float) operator double();
|
||||
}
|
||||
|
||||
var::operator double() const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case voidType: break;
|
||||
case intType: return value.intValue;
|
||||
case boolType: return value.boolValue ? 1.0 : 0.0;
|
||||
case doubleType: return value.doubleValue;
|
||||
case stringType: return value.stringValue->getDoubleValue();
|
||||
case objectType: break;
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const String var::toString() const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case voidType: return String::empty;
|
||||
case intType: return String (value.intValue);
|
||||
case boolType: return String::charToString (value.boolValue ? '1' : '0');
|
||||
case doubleType: return String (value.doubleValue);
|
||||
case stringType: return *(value.stringValue);
|
||||
case objectType: return "Object 0x" + String::toHexString ((int) (pointer_sized_int) value.objectValue);
|
||||
case methodType: return "Method";
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
var::operator const String() const
|
||||
{
|
||||
return toString();
|
||||
}
|
||||
|
||||
DynamicObject* var::getObject() const
|
||||
{
|
||||
return type == objectType ? value.objectValue : 0;
|
||||
}
|
||||
var& var::operator= (const var& newValue) { type->cleanUp (value); type = newValue.type; type->createCopy (value, newValue.value); return *this; }
|
||||
var& var::operator= (int newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (bool newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (double newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (const char* newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (const juce_wchar* newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (DynamicObject* newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; }
|
||||
|
||||
//==============================================================================
|
||||
bool var::equals (const var& other) const throw()
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case voidType: return other.isVoid();
|
||||
case intType: return value.intValue == static_cast <int> (other);
|
||||
case boolType: return value.boolValue == static_cast <bool> (other);
|
||||
case doubleType: return value.doubleValue == static_cast <double> (other);
|
||||
case stringType: return (*(value.stringValue)) == other.toString();
|
||||
case objectType: return value.objectValue == other.getObject();
|
||||
case methodType: return value.methodValue == other.value.methodValue && other.isMethod();
|
||||
default: jassertfalse; break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return type->equals (value, other.value, *other.type);
|
||||
}
|
||||
|
||||
bool operator== (const var& v1, const var& v2) throw() { return v1.equals (v2); }
|
||||
|
|
@ -236,26 +346,7 @@ bool operator!= (const var& v1, const String& v2) throw() { return v1.toString
|
|||
//==============================================================================
|
||||
void var::writeToStream (OutputStream& output) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case voidType: output.writeCompressedInt (0); break;
|
||||
case intType: output.writeCompressedInt (5); output.writeByte (1); output.writeInt (value.intValue); break;
|
||||
case boolType: output.writeCompressedInt (1); output.writeByte (value.boolValue ? 2 : 3); break;
|
||||
case doubleType: output.writeCompressedInt (9); output.writeByte (4); output.writeDouble (value.doubleValue); break;
|
||||
case stringType:
|
||||
{
|
||||
const int len = value.stringValue->getNumBytesAsUTF8() + 1;
|
||||
output.writeCompressedInt (len + 1);
|
||||
output.writeByte (5);
|
||||
HeapBlock<char> temp (len);
|
||||
value.stringValue->copyToUTF8 (temp, len);
|
||||
output.write (temp, len);
|
||||
break;
|
||||
}
|
||||
case objectType:
|
||||
case methodType: output.writeCompressedInt (0); jassertfalse; break; // Can't write an object to a stream!
|
||||
default: jassertfalse; break; // Is this a corrupted object?
|
||||
}
|
||||
type->writeToStream (value, output);
|
||||
}
|
||||
|
||||
const var var::readFromStream (InputStream& input)
|
||||
|
|
@ -286,18 +377,14 @@ const var var::readFromStream (InputStream& input)
|
|||
|
||||
const var var::operator[] (const Identifier& propertyName) const
|
||||
{
|
||||
if (type == objectType && value.objectValue != 0)
|
||||
return value.objectValue->getProperty (propertyName);
|
||||
|
||||
return var::null;
|
||||
DynamicObject* const o = getObject();
|
||||
return o != 0 ? o->getProperty (propertyName) : var::null;
|
||||
}
|
||||
|
||||
const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const
|
||||
{
|
||||
if (type == objectType && value.objectValue != 0)
|
||||
return value.objectValue->invokeMethod (method, arguments, numArguments);
|
||||
|
||||
return var::null;
|
||||
DynamicObject* const o = getObject();
|
||||
return o != 0 ? o->invokeMethod (method, arguments, numArguments) : var::null;
|
||||
}
|
||||
|
||||
const var var::invoke (const var& targetObject, const var* arguments, int numArguments) const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue