1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-22 01:34:21 +00:00

Performance optimisations to the way that Identifier objects are passed into var, ValueTree and NamedValueSet. The Identifer class used to be light enough to pass by value but now contains a String so is better passed by reference.

This commit is contained in:
jules 2015-06-21 18:54:08 +01:00
parent d7250c0a90
commit e018192de2
8 changed files with 97 additions and 75 deletions

View file

@ -584,7 +584,7 @@ public:
};
//==============================================================================
static NPIdentifier getIdentifierFromString (const var::identifier& s) noexcept
static NPIdentifier getIdentifierFromString (const Identifier& s) noexcept
{
return browser.getstringidentifier (s.toString().toUTF8());
}
@ -601,6 +601,7 @@ class DynamicObjectWrappingNPObject : public DynamicObject
{
NPP npp;
NPObject* const source;
mutable var returnValue;
public:
DynamicObjectWrappingNPObject (NPP npp_, NPObject* const source_)
@ -616,17 +617,20 @@ public:
DBG ("num NP wrapper objs: " + String (--numDOWNP));
}
var getProperty (const var::identifier& propertyName) const override
const var& getProperty (const Identifier& propertyName) const override
{
NPVariant result;
VOID_TO_NPVARIANT (result);
browser.getproperty (npp, source, getIdentifierFromString (propertyName), &result);
const var v (createValueFromNPVariant (npp, result));
// NB: this is just a workaorund for the return type being a reference - not too bothered
// about threading implications of this since this code will all soon be deprecated anyway.
returnValue = createValueFromNPVariant (npp, result);
browser.releasevariantvalue (&result);
return v;
return returnValue;
}
bool hasProperty (const var::identifier& propertyName) const override
bool hasProperty (const Identifier& propertyName) const override
{
NPVariant result;
VOID_TO_NPVARIANT (result);
@ -635,7 +639,7 @@ public:
return hasProp;
}
void setProperty (const var::identifier& propertyName, const var& newValue) override
void setProperty (const Identifier& propertyName, const var& newValue) override
{
NPVariant value;
createNPVariantFromValue (npp, value, newValue);
@ -644,12 +648,12 @@ public:
browser.releasevariantvalue (&value);
}
void removeProperty (const var::identifier& propertyName) override
void removeProperty (const Identifier& propertyName) override
{
browser.removeproperty (npp, source, getIdentifierFromString (propertyName));
}
bool hasMethod (const var::identifier& methodName) const override
bool hasMethod (const Identifier& methodName) const override
{
return browser.hasmethod (npp, source, getIdentifierFromString (methodName));
}
@ -721,7 +725,7 @@ private:
bool invoke (NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* out)
{
DynamicObject* const o = object.getDynamicObject();
const var::identifier methodName (identifierToString (name));
const Identifier methodName (identifierToString (name));
if (o == nullptr || ! o->hasMethod (methodName))
return false;
@ -761,7 +765,7 @@ private:
bool getProperty (NPIdentifier name, NPVariant* out)
{
DynamicObject* const o = object.getDynamicObject();
const var::identifier propName (identifierToString (name));
const Identifier propName (identifierToString (name));
if (o == nullptr || ! o->hasProperty (propName))
return false;
@ -788,7 +792,7 @@ private:
bool removeProperty (NPIdentifier name)
{
DynamicObject* const o = object.getDynamicObject();
const var::identifier propName (identifierToString (name));
const Identifier propName (identifierToString (name));
if (o == nullptr || ! o->hasProperty (propName))
return false;
@ -806,10 +810,10 @@ private:
NPP npp;
var object;
static var::identifier identifierToString (NPIdentifier id)
static Identifier identifierToString (NPIdentifier id)
{
NPUTF8* const name = browser.utf8fromidentifier (id);
const var::identifier result ((const char*) name);
const Identifier result ((const char*) name);
browser.memfree (name);
return result;
}

View file

@ -29,7 +29,7 @@
struct NamedValueSet::NamedValue
{
NamedValue() noexcept {}
NamedValue (Identifier n, const var& v) : name (n), value (v) {}
NamedValue (const Identifier& n, const var& v) : name (n), value (v) {}
NamedValue (const NamedValue& other) : name (other.name), value (other.value) {}
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
@ -39,7 +39,9 @@ struct NamedValueSet::NamedValue
{
}
NamedValue (Identifier n, var&& v) : name (n), value (static_cast<var&&> (v))
NamedValue (Identifier&& n, var&& v)
: name (static_cast<Identifier&&> (n)),
value (static_cast<var&&> (v))
{
}

View file

@ -576,7 +576,7 @@ var var::clone() const noexcept
}
//==============================================================================
const var& var::operator[] (Identifier propertyName) const
const var& var::operator[] (const Identifier& propertyName) const
{
if (DynamicObject* const o = getDynamicObject())
return o->getProperty (propertyName);
@ -589,7 +589,7 @@ const var& var::operator[] (const char* const propertyName) const
return operator[] (Identifier (propertyName));
}
var var::getProperty (const Identifier propertyName, const var& defaultReturnValue) const
var var::getProperty (const Identifier& propertyName, const var& defaultReturnValue) const
{
if (DynamicObject* const o = getDynamicObject())
return o->getProperties().getWithDefault (propertyName, defaultReturnValue);
@ -602,7 +602,7 @@ var::NativeFunction var::getNativeFunction() const
return isMethod() ? value.methodValue : nullptr;
}
var var::invoke (Identifier method, const var* arguments, int numArguments) const
var var::invoke (const Identifier& method, const var* arguments, int numArguments) const
{
if (DynamicObject* const o = getDynamicObject())
return o->invokeMethod (method, var::NativeFunctionArgs (*this, arguments, numArguments));
@ -610,35 +610,35 @@ var var::invoke (Identifier method, const var* arguments, int numArguments) cons
return var();
}
var var::call (const Identifier method) const
var var::call (const Identifier& method) const
{
return invoke (method, nullptr, 0);
}
var var::call (const Identifier method, const var& arg1) const
var var::call (const Identifier& method, const var& arg1) const
{
return invoke (method, &arg1, 1);
}
var var::call (const Identifier method, const var& arg1, const var& arg2) const
var var::call (const Identifier& method, const var& arg1, const var& arg2) const
{
var args[] = { arg1, arg2 };
return invoke (method, args, 2);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3)
var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3)
{
var args[] = { arg1, arg2, arg3 };
return invoke (method, args, 3);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
{
var args[] = { arg1, arg2, arg3, arg4 };
return invoke (method, args, 4);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
{
var args[] = { arg1, arg2, arg3, arg4, arg5 };
return invoke (method, args, 5);

View file

@ -62,7 +62,6 @@ public:
};
typedef var (*NativeFunction) (const NativeFunctionArgs&);
typedef Identifier identifier;
//==============================================================================
/** Creates a void variant. */
@ -242,27 +241,27 @@ public:
//==============================================================================
/** If this variant is an object, this returns one of its properties. */
const var& operator[] (Identifier propertyName) const;
const var& operator[] (const Identifier& propertyName) const;
/** If this variant is an object, this returns one of its properties. */
const 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 (Identifier propertyName, const var& defaultReturnValue) const;
var getProperty (const Identifier& propertyName, const var& defaultReturnValue) const;
/** Invokes a named method call with no arguments. */
var call (Identifier method) const;
var call (const Identifier& method) const;
/** Invokes a named method call with one argument. */
var call (Identifier method, const var& arg1) const;
var call (const 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;
var call (const 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);
var call (const 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;
var call (const 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;
var call (const 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;
var invoke (const Identifier& method, const var* arguments, int numArguments) const;
/** If this object is a method, this returns the function pointer. */
NativeFunction getNativeFunction() const;

View file

@ -31,7 +31,17 @@ Identifier::~Identifier() noexcept {}
Identifier::Identifier (const Identifier& other) noexcept : name (other.name) {}
Identifier& Identifier::operator= (const Identifier other) noexcept
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Identifier::Identifier (Identifier&& other) noexcept : name (static_cast<String&&> (other.name)) {}
Identifier& Identifier::operator= (Identifier&& other) noexcept
{
name = static_cast<String&&> (other.name);
return *this;
}
#endif
Identifier& Identifier::operator= (const Identifier& other) noexcept
{
name = other.name;
return *this;

View file

@ -68,16 +68,24 @@ public:
Identifier (const Identifier& other) noexcept;
/** Creates a copy of another identifier. */
Identifier& operator= (const Identifier other) noexcept;
Identifier& operator= (const Identifier& other) noexcept;
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Creates a copy of another identifier. */
Identifier (Identifier&& other) noexcept;
/** Creates a copy of another identifier. */
Identifier& operator= (Identifier&& other) noexcept;
#endif
/** Destructor */
~Identifier() noexcept;
/** Compares two identifiers. This is a very fast operation. */
inline bool operator== (Identifier other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); }
inline bool operator== (const Identifier& other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); }
/** Compares two identifiers. This is a very fast operation. */
inline bool operator!= (Identifier other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); }
inline bool operator!= (const Identifier& other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); }
/** Compares the identifier with a string. */
inline bool operator== (StringRef other) const noexcept { return name == other; }

View file

@ -27,7 +27,7 @@ class ValueTree::SharedObject : public ReferenceCountedObject
public:
typedef ReferenceCountedObjectPtr<SharedObject> Ptr;
explicit SharedObject (Identifier t) noexcept
explicit SharedObject (const Identifier& t) noexcept
: type (t), parent (nullptr)
{
}
@ -126,7 +126,7 @@ public:
}
}
void sendPropertyChangeMessage (const Identifier property)
void sendPropertyChangeMessage (const Identifier& property)
{
ValueTree tree (this);
@ -169,7 +169,7 @@ public:
callListeners (&ValueTree::Listener::valueTreeParentChanged, tree);
}
void setProperty (const Identifier name, const var& newValue, UndoManager* const undoManager)
void setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager)
{
if (undoManager == nullptr)
{
@ -190,12 +190,12 @@ public:
}
}
bool hasProperty (const Identifier name) const noexcept
bool hasProperty (const Identifier& name) const noexcept
{
return properties.contains (name);
}
void removeProperty (const Identifier name, UndoManager* const undoManager)
void removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (undoManager == nullptr)
{
@ -238,7 +238,7 @@ public:
setProperty (source.properties.getName(i), source.properties.getValueAt(i), undoManager);
}
ValueTree getChildWithName (const Identifier typeToMatch) const
ValueTree getChildWithName (const Identifier& typeToMatch) const
{
for (int i = 0; i < children.size(); ++i)
{
@ -250,7 +250,7 @@ public:
return ValueTree();
}
ValueTree getOrCreateChildWithName (const Identifier typeToMatch, UndoManager* undoManager)
ValueTree getOrCreateChildWithName (const Identifier& typeToMatch, UndoManager* undoManager)
{
for (int i = 0; i < children.size(); ++i)
{
@ -265,7 +265,7 @@ public:
}
ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const
ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
for (int i = 0; i < children.size(); ++i)
{
@ -458,7 +458,7 @@ public:
class SetPropertyAction : public UndoableAction
{
public:
SetPropertyAction (SharedObject* const so, const Identifier propertyName,
SetPropertyAction (SharedObject* const so, const Identifier& propertyName,
const var& newVal, const var& oldVal, bool isAdding, bool isDeleting)
: target (so), name (propertyName), newValue (newVal), oldValue (oldVal),
isAddingNewProperty (isAdding), isDeletingProperty (isDeleting)
@ -629,7 +629,7 @@ ValueTree::ValueTree() noexcept
const ValueTree ValueTree::invalid;
ValueTree::ValueTree (Identifier type) : object (new ValueTree::SharedObject (type))
ValueTree::ValueTree (const Identifier& type) : object (new ValueTree::SharedObject (type))
{
jassert (type.toString().isNotEmpty()); // All objects must be given a sensible type name!
}
@ -702,7 +702,7 @@ ValueTree ValueTree::createCopy() const
return ValueTree (createCopyIfNotNull (object.get()));
}
bool ValueTree::hasType (const Identifier typeName) const
bool ValueTree::hasType (const Identifier& typeName) const
{
return object != nullptr && object->type == typeName;
}
@ -727,24 +727,23 @@ ValueTree ValueTree::getSibling (const int delta) const
return ValueTree (object->parent->children.getObjectPointer (index));
}
const var& ValueTree::operator[] (const Identifier name) const
const var& ValueTree::operator[] (const Identifier& name) const
{
return object == nullptr ? var::null : object->properties[name];
}
const var& ValueTree::getProperty (const Identifier name) const
const var& ValueTree::getProperty (const Identifier& name) const
{
return object == nullptr ? var::null : object->properties[name];
}
var ValueTree::getProperty (const Identifier name, const var& defaultReturnValue) const
var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const
{
return object == nullptr ? defaultReturnValue
: object->properties.getWithDefault (name, defaultReturnValue);
}
ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue,
UndoManager* const undoManager)
ValueTree& ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager)
{
jassert (name.toString().isNotEmpty()); // Must have a valid property name!
jassert (object != nullptr); // Trying to add a property to a null ValueTree will fail!
@ -755,12 +754,12 @@ ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue,
return *this;
}
bool ValueTree::hasProperty (const Identifier name) const
bool ValueTree::hasProperty (const Identifier& name) const
{
return object != nullptr && object->hasProperty (name);
}
void ValueTree::removeProperty (const Identifier name, UndoManager* const undoManager)
void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (object != nullptr)
object->removeProperty (name, undoManager);
@ -803,7 +802,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource,
private ValueTree::Listener
{
public:
ValueTreePropertyValueSource (const ValueTree& vt, const Identifier prop, UndoManager* um)
ValueTreePropertyValueSource (const ValueTree& vt, const Identifier& prop, UndoManager* um)
: tree (vt), property (prop), undoManager (um)
{
tree.addListener (this);
@ -836,7 +835,7 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreePropertyValueSource)
};
Value ValueTree::getPropertyAsValue (const Identifier name, UndoManager* const undoManager)
Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager)
{
return Value (new ValueTreePropertyValueSource (*this, name, undoManager));
}
@ -853,17 +852,17 @@ ValueTree ValueTree::getChild (int index) const
: static_cast<SharedObject*> (nullptr));
}
ValueTree ValueTree::getChildWithName (const Identifier type) const
ValueTree ValueTree::getChildWithName (const Identifier& type) const
{
return object != nullptr ? object->getChildWithName (type) : ValueTree();
}
ValueTree ValueTree::getOrCreateChildWithName (const Identifier type, UndoManager* undoManager)
ValueTree ValueTree::getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager)
{
return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree();
}
ValueTree ValueTree::getChildWithProperty (const Identifier propertyName, const var& propertyValue) const
ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree();
}
@ -945,7 +944,7 @@ void ValueTree::removeListener (Listener* listener)
object->valueTreesWithListeners.removeValue (this);
}
void ValueTree::sendPropertyChangeMessage (const Identifier property)
void ValueTree::sendPropertyChangeMessage (const Identifier& property)
{
if (object != nullptr)
object->sendPropertyChangeMessage (property);

View file

@ -79,7 +79,7 @@ public:
Like an XmlElement, each ValueTree node has a type, which you can access with
getType() and hasType().
*/
explicit ValueTree (Identifier type);
explicit ValueTree (const Identifier& type);
/** Creates a reference to another ValueTree. */
ValueTree (const ValueTree&);
@ -134,7 +134,7 @@ public:
/** Returns true if the node has this type.
The comparison is case-sensitive.
*/
bool hasType (const Identifier typeName) const;
bool hasType (const Identifier& typeName) const;
//==============================================================================
/** Returns the value of a named property.
@ -142,21 +142,21 @@ public:
You can also use operator[] to get a property.
@see var, setProperty, hasProperty
*/
const var& getProperty (const Identifier name) const;
const var& getProperty (const Identifier& name) const;
/** Returns the value of a named property, or a user-specified default if the property doesn't exist.
If no such property has been set, this will return the value of defaultReturnValue.
You can also use operator[] and getProperty to get a property.
@see var, getProperty, setProperty, hasProperty
*/
var getProperty (const Identifier name, const var& defaultReturnValue) const;
var getProperty (const Identifier& name, const var& defaultReturnValue) const;
/** Returns the value of a named property.
If no such property has been set, this will return a void variant. This is the same as
calling getProperty().
@see getProperty
*/
const var& operator[] (const Identifier name) const;
const var& operator[] (const Identifier& name) const;
/** Changes a named property of the node.
The name identifier must not be an empty string.
@ -165,16 +165,16 @@ public:
@see var, getProperty, removeProperty
@returns a reference to the value tree, so that you can daisy-chain calls to this method.
*/
ValueTree& setProperty (const Identifier name, const var& newValue, UndoManager* undoManager);
ValueTree& setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager);
/** Returns true if the node contains a named property. */
bool hasProperty (const Identifier name) const;
bool hasProperty (const Identifier& name) const;
/** Removes a property from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
so that this change can be undone.
*/
void removeProperty (const Identifier name, UndoManager* undoManager);
void removeProperty (const Identifier& name, UndoManager* undoManager);
/** Removes all properties from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
@ -198,7 +198,7 @@ public:
it needs to change the value. Attaching a Value::Listener to the value object will provide
callbacks whenever the property changes.
*/
Value getPropertyAsValue (const Identifier name, UndoManager* undoManager);
Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager);
/** Overwrites all the properties in this tree with the properties of the source tree.
Any properties that already exist will be updated; and new ones will be added, and
@ -223,7 +223,7 @@ public:
whether a node is valid).
@see getOrCreateChildWithName
*/
ValueTree getChildWithName (const Identifier type) const;
ValueTree getChildWithName (const Identifier& type) const;
/** Returns the first child node with the speficied type name, creating and adding
a child with this name if there wasn't already one there.
@ -232,7 +232,7 @@ public:
the method on is itself invalid.
@see getChildWithName
*/
ValueTree getOrCreateChildWithName (const Identifier type, UndoManager* undoManager);
ValueTree getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager);
/** Looks for the first child node that has the speficied property value.
@ -242,7 +242,7 @@ public:
If no such node is found, it'll return an invalid node. (See isValid() to find out
whether a node is valid).
*/
ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const;
ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
/** Adds a child to this node.
@ -453,7 +453,7 @@ public:
/** Causes a property-change callback to be triggered for the specified property,
calling any listeners that are registered.
*/
void sendPropertyChangeMessage (const Identifier property);
void sendPropertyChangeMessage (const Identifier& property);
//==============================================================================
/** This method uses a comparator object to sort the tree's children into order.