- Library code update
- project update (added Eigen) git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@94 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
@@ -53,7 +53,7 @@ File PropertiesFile::Options::getDefaultFile() const
|
||||
File dir (commonToAllUsers ? "/Library/"
|
||||
: "~/Library/");
|
||||
|
||||
if (osxLibrarySubFolder != "Preferences" && osxLibrarySubFolder != "Application Support")
|
||||
if (osxLibrarySubFolder != "Preferences" && ! osxLibrarySubFolder.startsWith ("Application Support"))
|
||||
{
|
||||
/* The PropertiesFile class always used to put its settings files in "Library/Preferences", but Apple
|
||||
have changed their advice, and now stipulate that settings should go in "Library/Application Support".
|
||||
@@ -61,7 +61,8 @@ File PropertiesFile::Options::getDefaultFile() const
|
||||
Because older apps would be broken by a silent change in this class's behaviour, you must now
|
||||
explicitly set the osxLibrarySubFolder value to indicate which path you want to use.
|
||||
|
||||
In newer apps, you should always set this to "Application Support".
|
||||
In newer apps, you should always set this to "Application Support"
|
||||
or "Application Support/YourSubFolderName".
|
||||
|
||||
If your app needs to load settings files that were created by older versions of juce and
|
||||
you want to maintain backwards-compatibility, then you can set this to "Preferences".
|
||||
|
||||
@@ -85,7 +85,8 @@ public:
|
||||
Because older apps would be broken by a silent change in this class's behaviour, you must now
|
||||
explicitly set the osxLibrarySubFolder value to indicate which path you want to use.
|
||||
|
||||
In newer apps, you should always set this to "Application Support".
|
||||
In newer apps, you should always set this to "Application Support" or
|
||||
"Application Support/YourSubFolderName".
|
||||
|
||||
If your app needs to load settings files that were created by older versions of juce and
|
||||
you want to maintain backwards-compatibility, then you can set this to "Preferences".
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "juce_data_structures",
|
||||
"name": "JUCE data model helper classes",
|
||||
"version": "3.0.5",
|
||||
"version": "3.0.8",
|
||||
"description": "Classes for undo/redo management, and smart data structures.",
|
||||
"website": "http://www.juce.com/juce",
|
||||
"license": "GPL/Commercial",
|
||||
|
||||
@@ -29,10 +29,6 @@ struct UndoManager::ActionSet
|
||||
time (Time::getCurrentTime())
|
||||
{}
|
||||
|
||||
OwnedArray <UndoableAction> actions;
|
||||
String name;
|
||||
Time time;
|
||||
|
||||
bool perform() const
|
||||
{
|
||||
for (int i = 0; i < actions.size(); ++i)
|
||||
@@ -60,6 +56,10 @@ struct UndoManager::ActionSet
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
OwnedArray<UndoableAction> actions;
|
||||
String name;
|
||||
Time time;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
@@ -101,6 +101,19 @@ void UndoManager::setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep,
|
||||
|
||||
//==============================================================================
|
||||
bool UndoManager::perform (UndoableAction* const newAction, const String& actionName)
|
||||
{
|
||||
if (perform (newAction))
|
||||
{
|
||||
if (actionName.isNotEmpty())
|
||||
setCurrentTransactionName (actionName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UndoManager::perform (UndoableAction* const newAction)
|
||||
{
|
||||
if (newAction != nullptr)
|
||||
{
|
||||
@@ -113,9 +126,6 @@ bool UndoManager::perform (UndoableAction* const newAction, const String& action
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actionName.isNotEmpty())
|
||||
currentTransactionName = actionName;
|
||||
|
||||
if (action->perform())
|
||||
{
|
||||
ActionSet* actionSet = getCurrentSet();
|
||||
@@ -134,7 +144,7 @@ bool UndoManager::perform (UndoableAction* const newAction, const String& action
|
||||
}
|
||||
else
|
||||
{
|
||||
actionSet = new ActionSet (currentTransactionName);
|
||||
actionSet = new ActionSet (newTransactionName);
|
||||
transactions.insert (nextIndex, actionSet);
|
||||
++nextIndex;
|
||||
}
|
||||
@@ -174,23 +184,31 @@ void UndoManager::clearFutureTransactions()
|
||||
}
|
||||
}
|
||||
|
||||
void UndoManager::beginNewTransaction (const String& actionName)
|
||||
void UndoManager::beginNewTransaction() noexcept
|
||||
{
|
||||
newTransaction = true;
|
||||
currentTransactionName = actionName;
|
||||
beginNewTransaction (String());
|
||||
}
|
||||
|
||||
void UndoManager::setCurrentTransactionName (const String& newName)
|
||||
void UndoManager::beginNewTransaction (const String& actionName) noexcept
|
||||
{
|
||||
currentTransactionName = newName;
|
||||
newTransaction = true;
|
||||
newTransactionName = actionName;
|
||||
}
|
||||
|
||||
void UndoManager::setCurrentTransactionName (const String& newName) noexcept
|
||||
{
|
||||
if (newTransaction)
|
||||
newTransactionName = newName;
|
||||
else if (ActionSet* action = getCurrentSet())
|
||||
action->name = newName;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept { return transactions [nextIndex - 1]; }
|
||||
UndoManager::ActionSet* UndoManager::getNextSet() const noexcept { return transactions [nextIndex]; }
|
||||
|
||||
bool UndoManager::canUndo() const { return getCurrentSet() != nullptr; }
|
||||
bool UndoManager::canRedo() const { return getNextSet() != nullptr; }
|
||||
bool UndoManager::canUndo() const noexcept { return getCurrentSet() != nullptr; }
|
||||
bool UndoManager::canRedo() const noexcept { return getNextSet() != nullptr; }
|
||||
|
||||
bool UndoManager::undo()
|
||||
{
|
||||
@@ -267,7 +285,7 @@ bool UndoManager::undoCurrentTransactionOnly()
|
||||
return newTransaction ? false : undo();
|
||||
}
|
||||
|
||||
void UndoManager::getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const
|
||||
void UndoManager::getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const
|
||||
{
|
||||
if (! newTransaction)
|
||||
if (const ActionSet* const s = getCurrentSet())
|
||||
|
||||
@@ -98,16 +98,32 @@ public:
|
||||
//==============================================================================
|
||||
/** Performs an action and adds it to the undo history list.
|
||||
|
||||
@param action the action to perform - this will be deleted by the UndoManager
|
||||
when no longer needed
|
||||
@param action the action to perform - this object will be deleted by
|
||||
the UndoManager when no longer needed
|
||||
@returns true if the command succeeds - see UndoableAction::perform
|
||||
@see beginNewTransaction
|
||||
*/
|
||||
bool perform (UndoableAction* action);
|
||||
|
||||
/** Performs an action and also gives it a name.
|
||||
|
||||
@param action the action to perform - this object will be deleted by
|
||||
the UndoManager when no longer needed
|
||||
@param actionName if this string is non-empty, the current transaction will be
|
||||
given this name; if it's empty, the current transaction name will
|
||||
be left unchanged. See setCurrentTransactionName()
|
||||
@returns true if the command succeeds - see UndoableAction::perform
|
||||
@see beginNewTransaction
|
||||
*/
|
||||
bool perform (UndoableAction* action,
|
||||
const String& actionName = String());
|
||||
bool perform (UndoableAction* action, const String& actionName);
|
||||
|
||||
/** Starts a new group of actions that together will be treated as a single transaction.
|
||||
|
||||
All actions that are passed to the perform() method between calls to this
|
||||
method are grouped together and undone/redone together by a single call to
|
||||
undo() or redo().
|
||||
*/
|
||||
void beginNewTransaction() noexcept;
|
||||
|
||||
/** Starts a new group of actions that together will be treated as a single transaction.
|
||||
|
||||
@@ -118,7 +134,7 @@ public:
|
||||
@param actionName a description of the transaction that is about to be
|
||||
performed
|
||||
*/
|
||||
void beginNewTransaction (const String& actionName = String());
|
||||
void beginNewTransaction (const String& actionName) noexcept;
|
||||
|
||||
/** Changes the name stored for the current transaction.
|
||||
|
||||
@@ -126,19 +142,15 @@ public:
|
||||
called, but this can be used to change that name without starting a new
|
||||
transaction.
|
||||
*/
|
||||
void setCurrentTransactionName (const String& newName);
|
||||
void setCurrentTransactionName (const String& newName) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if there's at least one action in the list to undo.
|
||||
@see getUndoDescription, undo, canRedo
|
||||
*/
|
||||
bool canUndo() const;
|
||||
|
||||
/** Returns the description of the transaction that would be next to get undone.
|
||||
|
||||
The description returned is the one that was passed into beginNewTransaction
|
||||
before the set of actions was performed.
|
||||
bool canUndo() const noexcept;
|
||||
|
||||
/** Returns the name of the transaction that will be rolled-back when undo() is called.
|
||||
@see undo
|
||||
*/
|
||||
String getUndoDescription() const;
|
||||
@@ -172,7 +184,7 @@ public:
|
||||
|
||||
The first item in the list is the earliest action performed.
|
||||
*/
|
||||
void getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const;
|
||||
void getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const;
|
||||
|
||||
/** Returns the number of UndoableAction objects that have been performed during the
|
||||
transaction that is currently open.
|
||||
@@ -194,12 +206,9 @@ public:
|
||||
/** Returns true if there's at least one action in the list to redo.
|
||||
@see getRedoDescription, redo, canUndo
|
||||
*/
|
||||
bool canRedo() const;
|
||||
|
||||
/** Returns the description of the transaction that would be next to get redone.
|
||||
The description returned is the one that was passed into beginNewTransaction
|
||||
before the set of actions was performed.
|
||||
bool canRedo() const noexcept;
|
||||
|
||||
/** Returns the name of the transaction that will be redone when redo() is called.
|
||||
@see redo
|
||||
*/
|
||||
String getRedoDescription() const;
|
||||
@@ -216,7 +225,7 @@ private:
|
||||
struct ActionSet;
|
||||
friend struct ContainerDeletePolicy<ActionSet>;
|
||||
OwnedArray<ActionSet> transactions;
|
||||
String currentTransactionName;
|
||||
String newTransactionName;
|
||||
int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex;
|
||||
bool newTransaction, reentrancyCheck;
|
||||
ActionSet* getCurrentSet() const noexcept;
|
||||
|
||||
@@ -22,76 +22,18 @@
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
class SharedValueSourceUpdater : public ReferenceCountedObject,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
SharedValueSourceUpdater() : sourcesBeingIterated (nullptr) {}
|
||||
~SharedValueSourceUpdater() { masterReference.clear(); }
|
||||
|
||||
void update (Value::ValueSource* const source)
|
||||
{
|
||||
sourcesNeedingAnUpdate.add (source);
|
||||
|
||||
if (sourcesBeingIterated == nullptr)
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void valueDeleted (Value::ValueSource* const source)
|
||||
{
|
||||
sourcesNeedingAnUpdate.removeValue (source);
|
||||
|
||||
if (sourcesBeingIterated != nullptr)
|
||||
sourcesBeingIterated->removeValue (source);
|
||||
}
|
||||
|
||||
WeakReference<SharedValueSourceUpdater>::Master masterReference;
|
||||
|
||||
private:
|
||||
typedef SortedSet<Value::ValueSource*> SourceSet;
|
||||
SourceSet sourcesNeedingAnUpdate;
|
||||
SourceSet* sourcesBeingIterated;
|
||||
|
||||
void handleAsyncUpdate() override
|
||||
{
|
||||
const ReferenceCountedObjectPtr<SharedValueSourceUpdater> localRef (this);
|
||||
|
||||
{
|
||||
const ScopedValueSetter<SourceSet*> inside (sourcesBeingIterated, nullptr, nullptr);
|
||||
int maxLoops = 10;
|
||||
|
||||
while (sourcesNeedingAnUpdate.size() > 0)
|
||||
{
|
||||
if (--maxLoops == 0)
|
||||
{
|
||||
triggerAsyncUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
SourceSet sources;
|
||||
sources.swapWith (sourcesNeedingAnUpdate);
|
||||
sourcesBeingIterated = &sources;
|
||||
|
||||
for (int i = sources.size(); --i >= 0;)
|
||||
if (i < sources.size())
|
||||
sources.getUnchecked(i)->sendChangeMessage (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedValueSourceUpdater)
|
||||
};
|
||||
|
||||
static WeakReference<SharedValueSourceUpdater> sharedUpdater;
|
||||
|
||||
Value::ValueSource::ValueSource()
|
||||
{
|
||||
}
|
||||
|
||||
Value::ValueSource::~ValueSource()
|
||||
{
|
||||
if (asyncUpdater != nullptr)
|
||||
static_cast <SharedValueSourceUpdater*> (asyncUpdater.get())->valueDeleted (this);
|
||||
cancelPendingUpdate();
|
||||
}
|
||||
|
||||
void Value::ValueSource::handleAsyncUpdate()
|
||||
{
|
||||
sendChangeMessage (true);
|
||||
}
|
||||
|
||||
void Value::ValueSource::sendChangeMessage (const bool synchronous)
|
||||
@@ -103,7 +45,8 @@ void Value::ValueSource::sendChangeMessage (const bool synchronous)
|
||||
if (synchronous)
|
||||
{
|
||||
const ReferenceCountedObjectPtr<ValueSource> localRef (this);
|
||||
asyncUpdater = nullptr;
|
||||
|
||||
cancelPendingUpdate();
|
||||
|
||||
for (int i = numListeners; --i >= 0;)
|
||||
if (Value* const v = valuesWithListeners[i])
|
||||
@@ -111,22 +54,7 @@ void Value::ValueSource::sendChangeMessage (const bool synchronous)
|
||||
}
|
||||
else
|
||||
{
|
||||
SharedValueSourceUpdater* updater = static_cast <SharedValueSourceUpdater*> (asyncUpdater.get());
|
||||
|
||||
if (updater == nullptr)
|
||||
{
|
||||
if (sharedUpdater == nullptr)
|
||||
{
|
||||
asyncUpdater = updater = new SharedValueSourceUpdater();
|
||||
sharedUpdater = updater;
|
||||
}
|
||||
else
|
||||
{
|
||||
asyncUpdater = updater = sharedUpdater.get();
|
||||
}
|
||||
}
|
||||
|
||||
updater->update (this);
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,24 +94,20 @@ private:
|
||||
|
||||
|
||||
//==============================================================================
|
||||
Value::Value()
|
||||
: value (new SimpleValueSource())
|
||||
Value::Value() : value (new SimpleValueSource())
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value (ValueSource* const v)
|
||||
: value (v)
|
||||
Value::Value (ValueSource* const v) : value (v)
|
||||
{
|
||||
jassert (v != nullptr);
|
||||
}
|
||||
|
||||
Value::Value (const var& initialValue)
|
||||
: value (new SimpleValueSource (initialValue))
|
||||
Value::Value (const var& initialValue) : value (new SimpleValueSource (initialValue))
|
||||
{
|
||||
}
|
||||
|
||||
Value::Value (const Value& other)
|
||||
: value (other.value)
|
||||
Value::Value (const Value& other) : value (other.value)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -195,20 +119,35 @@ Value& Value::operator= (const Value& other)
|
||||
|
||||
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
Value::Value (Value&& other) noexcept
|
||||
: value (static_cast <ReferenceCountedObjectPtr <ValueSource>&&> (other.value))
|
||||
{
|
||||
// moving a Value with listeners will lose those listeners, which
|
||||
// probably isn't what you wanted to happen!
|
||||
jassert (other.listeners.size() == 0);
|
||||
|
||||
other.removeFromListenerList();
|
||||
value = static_cast<ReferenceCountedObjectPtr<ValueSource>&&> (other.value);
|
||||
}
|
||||
|
||||
Value& Value::operator= (Value&& other) noexcept
|
||||
{
|
||||
value = static_cast <ReferenceCountedObjectPtr <ValueSource>&&> (other.value);
|
||||
// moving a Value with listeners will lose those listeners, which
|
||||
// probably isn't what you wanted to happen!
|
||||
jassert (other.listeners.size() == 0);
|
||||
|
||||
other.removeFromListenerList();
|
||||
value = static_cast<ReferenceCountedObjectPtr<ValueSource>&&> (other.value);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
Value::~Value()
|
||||
{
|
||||
if (listeners.size() > 0)
|
||||
removeFromListenerList();
|
||||
}
|
||||
|
||||
void Value::removeFromListenerList()
|
||||
{
|
||||
if (listeners.size() > 0 && value != nullptr) // may be nullptr after a move operation
|
||||
value->valuesWithListeners.removeValue (this);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,9 +147,9 @@ public:
|
||||
The listener is added to this specific Value object, and not to the shared
|
||||
object that it refers to. When this object is deleted, all the listeners will
|
||||
be lost, even if other references to the same Value still exist. So when you're
|
||||
adding a listener, make sure that you add it to a ValueTree instance that will last
|
||||
adding a listener, make sure that you add it to a Value instance that will last
|
||||
for as long as you need the listener. In general, you'd never want to add a listener
|
||||
to a local stack-based ValueTree, but more likely to one that's a member variable.
|
||||
to a local stack-based Value, but more likely to one that's a member variable.
|
||||
|
||||
@see removeListener
|
||||
*/
|
||||
@@ -167,7 +167,8 @@ public:
|
||||
of a ValueSource object. If you're feeling adventurous, you can create your own custom
|
||||
ValueSource classes to allow Value objects to represent your own custom data items.
|
||||
*/
|
||||
class JUCE_API ValueSource : public SingleThreadedReferenceCountedObject
|
||||
class JUCE_API ValueSource : public ReferenceCountedObject,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
ValueSource();
|
||||
@@ -192,8 +193,10 @@ public:
|
||||
protected:
|
||||
//==============================================================================
|
||||
friend class Value;
|
||||
SortedSet <Value*> valuesWithListeners;
|
||||
ReferenceCountedObjectPtr<ReferenceCountedObject> asyncUpdater;
|
||||
SortedSet<Value*> valuesWithListeners;
|
||||
|
||||
private:
|
||||
void handleAsyncUpdate() override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSource)
|
||||
};
|
||||
@@ -210,10 +213,11 @@ public:
|
||||
private:
|
||||
//==============================================================================
|
||||
friend class ValueSource;
|
||||
ReferenceCountedObjectPtr <ValueSource> value;
|
||||
ListenerList <Listener> listeners;
|
||||
ReferenceCountedObjectPtr<ValueSource> value;
|
||||
ListenerList<Listener> listeners;
|
||||
|
||||
void callListeners();
|
||||
void removeFromListenerList();
|
||||
|
||||
// This is disallowed to avoid confusion about whether it should
|
||||
// do a by-value or by-reference copy.
|
||||
|
||||
@@ -409,7 +409,7 @@ public:
|
||||
|
||||
XmlElement* createXml() const
|
||||
{
|
||||
XmlElement* const xml = new XmlElement (type.toString());
|
||||
XmlElement* const xml = new XmlElement (type);
|
||||
properties.copyToXmlAttributes (*xml);
|
||||
|
||||
// (NB: it's faster to add nodes to XML elements in reverse order)
|
||||
@@ -789,6 +789,11 @@ void ValueTree::copyPropertiesFrom (const ValueTree& source, UndoManager* const
|
||||
object->copyPropertiesFrom (*(source.object), undoManager);
|
||||
}
|
||||
|
||||
int ValueTree::getReferenceCount() const noexcept
|
||||
{
|
||||
return object != nullptr ? object->getReferenceCount() : 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class ValueTreePropertyValueSource : public Value::ValueSource,
|
||||
private ValueTree::Listener
|
||||
@@ -950,6 +955,9 @@ XmlElement* ValueTree::createXml() const
|
||||
|
||||
ValueTree ValueTree::fromXml (const XmlElement& xml)
|
||||
{
|
||||
// ValueTrees don't have any equivalent to XML text elements!
|
||||
jassert (! xml.isTextElement());
|
||||
|
||||
ValueTree v (xml.getTagName());
|
||||
v.object->properties.setFromXmlAttributes (xml);
|
||||
|
||||
|
||||
@@ -318,7 +318,10 @@ public:
|
||||
/** Creates an XmlElement that holds a complete image of this node and all its children.
|
||||
|
||||
If this node is invalid, this may return nullptr. Otherwise, the XML that is produced can
|
||||
be used to recreate a similar node by calling fromXml()
|
||||
be used to recreate a similar node by calling fromXml().
|
||||
|
||||
The caller must delete the object that is returned.
|
||||
|
||||
@see fromXml
|
||||
*/
|
||||
XmlElement* createXml() const;
|
||||
@@ -490,6 +493,11 @@ public:
|
||||
*/
|
||||
static const ValueTree invalid;
|
||||
|
||||
/** Returns the total number of references to the shared underlying data structure that this
|
||||
ValueTree is using.
|
||||
*/
|
||||
int getReferenceCount() const noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
JUCE_PUBLIC_IN_DLL_BUILD (class SharedObject)
|
||||
|
||||
Reference in New Issue
Block a user