| @@ -2341,7 +2341,13 @@ AbstractFifo::~AbstractFifo() {} | |||||
| int AbstractFifo::getTotalSize() const throw() { return bufferSize; } | int AbstractFifo::getTotalSize() const throw() { return bufferSize; } | ||||
| int AbstractFifo::getFreeSpace() const throw() { return bufferSize - getNumReady(); } | int AbstractFifo::getFreeSpace() const throw() { return bufferSize - getNumReady(); } | ||||
| int AbstractFifo::getNumReady() const throw() { return validEnd.get() - validStart.get(); } | |||||
| int AbstractFifo::getNumReady() const throw() | |||||
| { | |||||
| const int vs = validStart.get(); | |||||
| const int ve = validEnd.get(); | |||||
| return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); | |||||
| } | |||||
| void AbstractFifo::reset() throw() | void AbstractFifo::reset() throw() | ||||
| { | { | ||||
| @@ -2359,10 +2365,10 @@ void AbstractFifo::setTotalSize (int newSize) throw() | |||||
| void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | ||||
| { | { | ||||
| const int vs = validStart.get(); | const int vs = validStart.get(); | ||||
| const int ve = validEnd.get(); | |||||
| const int ve = validEnd.value; | |||||
| const int freeSpace = bufferSize - (ve - vs); | |||||
| numToWrite = jmin (numToWrite, freeSpace); | |||||
| const int freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve); | |||||
| numToWrite = jmin (numToWrite, freeSpace - 1); | |||||
| if (numToWrite <= 0) | if (numToWrite <= 0) | ||||
| { | { | ||||
| @@ -2373,26 +2379,30 @@ void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockS | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| startIndex1 = (int) (ve % bufferSize); | |||||
| startIndex1 = ve; | |||||
| startIndex2 = 0; | startIndex2 = 0; | ||||
| blockSize1 = jmin (bufferSize - startIndex1, numToWrite); | |||||
| blockSize1 = jmin (bufferSize - ve, numToWrite); | |||||
| numToWrite -= blockSize1; | numToWrite -= blockSize1; | ||||
| blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, (int) (vs % bufferSize)); | |||||
| blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, vs); | |||||
| } | } | ||||
| } | } | ||||
| void AbstractFifo::finishedWrite (int numWritten) throw() | void AbstractFifo::finishedWrite (int numWritten) throw() | ||||
| { | { | ||||
| jassert (numWritten >= 0 && numWritten < bufferSize); | jassert (numWritten >= 0 && numWritten < bufferSize); | ||||
| validEnd += numWritten; | |||||
| int newEnd = validEnd.value + numWritten; | |||||
| if (newEnd >= bufferSize) | |||||
| newEnd -= bufferSize; | |||||
| validEnd = newEnd; | |||||
| } | } | ||||
| void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | ||||
| { | { | ||||
| const int vs = validStart.get(); | |||||
| const int vs = validStart.value; | |||||
| const int ve = validEnd.get(); | const int ve = validEnd.get(); | ||||
| const int numReady = ve - vs; | |||||
| const int numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); | |||||
| numWanted = jmin (numWanted, numReady); | numWanted = jmin (numWanted, numReady); | ||||
| if (numWanted <= 0) | if (numWanted <= 0) | ||||
| @@ -2404,20 +2414,127 @@ void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSiz | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| startIndex1 = (int) (vs % bufferSize); | |||||
| startIndex1 = vs; | |||||
| startIndex2 = 0; | startIndex2 = 0; | ||||
| blockSize1 = jmin (bufferSize - startIndex1, numWanted); | |||||
| blockSize1 = jmin (bufferSize - vs, numWanted); | |||||
| numWanted -= blockSize1; | numWanted -= blockSize1; | ||||
| blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, (int) (ve % bufferSize)); | |||||
| blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, ve); | |||||
| } | } | ||||
| } | } | ||||
| void AbstractFifo::finishedRead (int numRead) throw() | void AbstractFifo::finishedRead (int numRead) throw() | ||||
| { | { | ||||
| jassert (numRead >= 0 && numRead < bufferSize); | |||||
| validStart += numRead; | |||||
| jassert (numRead >= 0 && numRead <= bufferSize); | |||||
| int newStart = validStart.value + numRead; | |||||
| if (newStart >= bufferSize) | |||||
| newStart -= bufferSize; | |||||
| validStart = newStart; | |||||
| } | } | ||||
| #if JUCE_UNIT_TESTS | |||||
| class AbstractFifoTests : public UnitTest | |||||
| { | |||||
| public: | |||||
| AbstractFifoTests() : UnitTest ("Abstract Fifo") {} | |||||
| class WriteThread : public Thread | |||||
| { | |||||
| public: | |||||
| WriteThread (AbstractFifo& fifo_, int* buffer_) | |||||
| : Thread ("fifo writer"), fifo (fifo_), buffer (buffer_) | |||||
| { | |||||
| startThread(); | |||||
| } | |||||
| ~WriteThread() | |||||
| { | |||||
| stopThread (5000); | |||||
| } | |||||
| void run() | |||||
| { | |||||
| int n = 0; | |||||
| while (! threadShouldExit()) | |||||
| { | |||||
| int num = Random::getSystemRandom().nextInt (2000) + 1; | |||||
| int start1, size1, start2, size2; | |||||
| fifo.prepareToWrite (num, start1, size1, start2, size2); | |||||
| jassert (size1 >= 0 && size2 >= 0); | |||||
| jassert (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())); | |||||
| jassert (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize())); | |||||
| int i; | |||||
| for (i = 0; i < size1; ++i) | |||||
| buffer [start1 + i] = n++; | |||||
| for (i = 0; i < size2; ++i) | |||||
| buffer [start2 + i] = n++; | |||||
| fifo.finishedWrite (size1 + size2); | |||||
| } | |||||
| } | |||||
| private: | |||||
| AbstractFifo& fifo; | |||||
| int* buffer; | |||||
| }; | |||||
| void runTest() | |||||
| { | |||||
| beginTest ("AbstractFifo"); | |||||
| int buffer [5000]; | |||||
| AbstractFifo fifo (numElementsInArray (buffer)); | |||||
| WriteThread writer (fifo, buffer); | |||||
| int n = 0; | |||||
| for (int count = 1000000; --count >= 0;) | |||||
| { | |||||
| int num = Random::getSystemRandom().nextInt (6000) + 1; | |||||
| int start1, size1, start2, size2; | |||||
| fifo.prepareToRead (num, start1, size1, start2, size2); | |||||
| if (! (size1 >= 0 && size2 >= 0) | |||||
| && (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())) | |||||
| && (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize()))) | |||||
| { | |||||
| expect (false, "prepareToRead returned -ve values"); | |||||
| break; | |||||
| } | |||||
| bool failed = false; | |||||
| int i; | |||||
| for (i = 0; i < size1; ++i) | |||||
| failed = (buffer [start1 + i] != n++) || failed; | |||||
| for (i = 0; i < size2; ++i) | |||||
| failed = (buffer [start2 + i] != n++) || failed; | |||||
| if (failed) | |||||
| { | |||||
| expect (false, "read values were incorrect"); | |||||
| break; | |||||
| } | |||||
| fifo.finishedRead (size1 + size2); | |||||
| } | |||||
| } | |||||
| }; | |||||
| static AbstractFifoTests fifoUnitTests; | |||||
| #endif | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| /*** End of inlined file: juce_AbstractFifo.cpp ***/ | /*** End of inlined file: juce_AbstractFifo.cpp ***/ | ||||
| @@ -4948,7 +5065,12 @@ public: | |||||
| visitor.useSymbol (Symbol (scope.getScopeUID(), getSymbol()->symbol)); | visitor.useSymbol (Symbol (scope.getScopeUID(), getSymbol()->symbol)); | ||||
| SymbolVisitingVisitor v (right, visitor, recursionDepth + 1); | SymbolVisitingVisitor v (right, visitor, recursionDepth + 1); | ||||
| scope.visitRelativeScope (getSymbol()->symbol, v); | |||||
| try | |||||
| { | |||||
| scope.visitRelativeScope (getSymbol()->symbol, v); | |||||
| } | |||||
| catch (...) {} | |||||
| } | } | ||||
| void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) | void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) | ||||
| @@ -4957,7 +5079,12 @@ public: | |||||
| getSymbol()->renameSymbol (oldSymbol, newName, scope, recursionDepth); | getSymbol()->renameSymbol (oldSymbol, newName, scope, recursionDepth); | ||||
| SymbolRenamingVisitor visitor (right, oldSymbol, newName, recursionDepth + 1); | SymbolRenamingVisitor visitor (right, oldSymbol, newName, recursionDepth + 1); | ||||
| scope.visitRelativeScope (getSymbol()->symbol, visitor); | |||||
| try | |||||
| { | |||||
| scope.visitRelativeScope (getSymbol()->symbol, visitor); | |||||
| } | |||||
| catch (...) {} | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -5792,8 +5919,9 @@ double Expression::Scope::evaluateFunction (const String& functionName, const do | |||||
| throw Helpers::EvaluationError ("Unknown function: \"" + functionName + "\""); | throw Helpers::EvaluationError ("Unknown function: \"" + functionName + "\""); | ||||
| } | } | ||||
| void Expression::Scope::visitRelativeScope (const String&, Visitor&) const | |||||
| void Expression::Scope::visitRelativeScope (const String& scopeName, Visitor&) const | |||||
| { | { | ||||
| throw Helpers::EvaluationError ("Unknown symbol: " + scopeName); | |||||
| } | } | ||||
| const String Expression::Scope::getScopeUID() const | const String Expression::Scope::getScopeUID() const | ||||
| @@ -61611,7 +61739,7 @@ namespace ComponentBuilderHelpers | |||||
| const ValueTree& state, Component* parent) | const ValueTree& state, Component* parent) | ||||
| { | { | ||||
| Component* const c = type.addNewComponentFromState (state, parent); | Component* const c = type.addNewComponentFromState (state, parent); | ||||
| jassert (c != 0); | |||||
| jassert (c != 0 && c->getParentComponent() == parent); | |||||
| c->setComponentID (getStateId (state)); | c->setComponentID (getStateId (state)); | ||||
| return c; | return c; | ||||
| } | } | ||||
| @@ -80376,6 +80504,8 @@ void RelativeCoordinatePositionerBase::ComponentScope::visitRelativeScope (const | |||||
| if (targetComp != 0) | if (targetComp != 0) | ||||
| visitor.visit (ComponentScope (*targetComp)); | visitor.visit (ComponentScope (*targetComp)); | ||||
| else | |||||
| Expression::Scope::visitRelativeScope (scopeName, visitor); | |||||
| } | } | ||||
| const String RelativeCoordinatePositionerBase::ComponentScope::getScopeUID() const | const String RelativeCoordinatePositionerBase::ComponentScope::getScopeUID() const | ||||
| @@ -80479,6 +80609,10 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| // The named component doesn't exist, so we'll watch the parent for changes in case it appears later.. | // The named component doesn't exist, so we'll watch the parent for changes in case it appears later.. | ||||
| Component* const parent = component.getParentComponent(); | |||||
| if (parent != 0) | |||||
| positioner.registerComponentListener (*parent); | |||||
| positioner.registerComponentListener (component); | positioner.registerComponentListener (component); | ||||
| ok = false; | ok = false; | ||||
| } | } | ||||
| @@ -80511,10 +80645,17 @@ void RelativeCoordinatePositionerBase::componentParentHierarchyChanged (Componen | |||||
| apply(); | apply(); | ||||
| } | } | ||||
| void RelativeCoordinatePositionerBase::componentChildrenChanged (Component& changed) | |||||
| { | |||||
| if (getComponent().getParentComponent() == &changed && ! registeredOk) | |||||
| apply(); | |||||
| } | |||||
| void RelativeCoordinatePositionerBase::componentBeingDeleted (Component& component) | void RelativeCoordinatePositionerBase::componentBeingDeleted (Component& component) | ||||
| { | { | ||||
| jassert (sourceComponents.contains (&component)); | jassert (sourceComponents.contains (&component)); | ||||
| sourceComponents.removeValue (&component); | sourceComponents.removeValue (&component); | ||||
| registeredOk = false; | |||||
| } | } | ||||
| void RelativeCoordinatePositionerBase::markersChanged (MarkerList*) | void RelativeCoordinatePositionerBase::markersChanged (MarkerList*) | ||||
| @@ -45966,6 +45966,7 @@ public: | |||||
| void componentMovedOrResized (Component&, bool, bool); | void componentMovedOrResized (Component&, bool, bool); | ||||
| void componentParentHierarchyChanged (Component&); | void componentParentHierarchyChanged (Component&); | ||||
| void componentChildrenChanged (Component& component); | |||||
| void componentBeingDeleted (Component& component); | void componentBeingDeleted (Component& component); | ||||
| void markersChanged (MarkerList*); | void markersChanged (MarkerList*); | ||||
| void markerListBeingDeleted (MarkerList* markerList); | void markerListBeingDeleted (MarkerList* markerList); | ||||
| @@ -41,7 +41,13 @@ AbstractFifo::~AbstractFifo() {} | |||||
| int AbstractFifo::getTotalSize() const throw() { return bufferSize; } | int AbstractFifo::getTotalSize() const throw() { return bufferSize; } | ||||
| int AbstractFifo::getFreeSpace() const throw() { return bufferSize - getNumReady(); } | int AbstractFifo::getFreeSpace() const throw() { return bufferSize - getNumReady(); } | ||||
| int AbstractFifo::getNumReady() const throw() { return validEnd.get() - validStart.get(); } | |||||
| int AbstractFifo::getNumReady() const throw() | |||||
| { | |||||
| const int vs = validStart.get(); | |||||
| const int ve = validEnd.get(); | |||||
| return ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); | |||||
| } | |||||
| void AbstractFifo::reset() throw() | void AbstractFifo::reset() throw() | ||||
| { | { | ||||
| @@ -60,10 +66,10 @@ void AbstractFifo::setTotalSize (int newSize) throw() | |||||
| void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | ||||
| { | { | ||||
| const int vs = validStart.get(); | const int vs = validStart.get(); | ||||
| const int ve = validEnd.get(); | |||||
| const int ve = validEnd.value; | |||||
| const int freeSpace = bufferSize - (ve - vs); | |||||
| numToWrite = jmin (numToWrite, freeSpace); | |||||
| const int freeSpace = ve >= vs ? (bufferSize - (ve - vs)) : (vs - ve); | |||||
| numToWrite = jmin (numToWrite, freeSpace - 1); | |||||
| if (numToWrite <= 0) | if (numToWrite <= 0) | ||||
| { | { | ||||
| @@ -74,26 +80,30 @@ void AbstractFifo::prepareToWrite (int numToWrite, int& startIndex1, int& blockS | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| startIndex1 = (int) (ve % bufferSize); | |||||
| startIndex1 = ve; | |||||
| startIndex2 = 0; | startIndex2 = 0; | ||||
| blockSize1 = jmin (bufferSize - startIndex1, numToWrite); | |||||
| blockSize1 = jmin (bufferSize - ve, numToWrite); | |||||
| numToWrite -= blockSize1; | numToWrite -= blockSize1; | ||||
| blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, (int) (vs % bufferSize)); | |||||
| blockSize2 = numToWrite <= 0 ? 0 : jmin (numToWrite, vs); | |||||
| } | } | ||||
| } | } | ||||
| void AbstractFifo::finishedWrite (int numWritten) throw() | void AbstractFifo::finishedWrite (int numWritten) throw() | ||||
| { | { | ||||
| jassert (numWritten >= 0 && numWritten < bufferSize); | jassert (numWritten >= 0 && numWritten < bufferSize); | ||||
| validEnd += numWritten; | |||||
| int newEnd = validEnd.value + numWritten; | |||||
| if (newEnd >= bufferSize) | |||||
| newEnd -= bufferSize; | |||||
| validEnd = newEnd; | |||||
| } | } | ||||
| void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSize1, int& startIndex2, int& blockSize2) const throw() | ||||
| { | { | ||||
| const int vs = validStart.get(); | |||||
| const int vs = validStart.value; | |||||
| const int ve = validEnd.get(); | const int ve = validEnd.get(); | ||||
| const int numReady = ve - vs; | |||||
| const int numReady = ve >= vs ? (ve - vs) : (bufferSize - (vs - ve)); | |||||
| numWanted = jmin (numWanted, numReady); | numWanted = jmin (numWanted, numReady); | ||||
| if (numWanted <= 0) | if (numWanted <= 0) | ||||
| @@ -105,19 +115,132 @@ void AbstractFifo::prepareToRead (int numWanted, int& startIndex1, int& blockSiz | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| startIndex1 = (int) (vs % bufferSize); | |||||
| startIndex1 = vs; | |||||
| startIndex2 = 0; | startIndex2 = 0; | ||||
| blockSize1 = jmin (bufferSize - startIndex1, numWanted); | |||||
| blockSize1 = jmin (bufferSize - vs, numWanted); | |||||
| numWanted -= blockSize1; | numWanted -= blockSize1; | ||||
| blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, (int) (ve % bufferSize)); | |||||
| blockSize2 = numWanted <= 0 ? 0 : jmin (numWanted, ve); | |||||
| } | } | ||||
| } | } | ||||
| void AbstractFifo::finishedRead (int numRead) throw() | void AbstractFifo::finishedRead (int numRead) throw() | ||||
| { | { | ||||
| jassert (numRead >= 0 && numRead < bufferSize); | |||||
| validStart += numRead; | |||||
| jassert (numRead >= 0 && numRead <= bufferSize); | |||||
| int newStart = validStart.value + numRead; | |||||
| if (newStart >= bufferSize) | |||||
| newStart -= bufferSize; | |||||
| validStart = newStart; | |||||
| } | } | ||||
| //============================================================================== | |||||
| //============================================================================== | |||||
| #if JUCE_UNIT_TESTS | |||||
| #include "../utilities/juce_UnitTest.h" | |||||
| #include "../maths/juce_Random.h" | |||||
| #include "../threads/juce_Thread.h" | |||||
| class AbstractFifoTests : public UnitTest | |||||
| { | |||||
| public: | |||||
| AbstractFifoTests() : UnitTest ("Abstract Fifo") {} | |||||
| class WriteThread : public Thread | |||||
| { | |||||
| public: | |||||
| WriteThread (AbstractFifo& fifo_, int* buffer_) | |||||
| : Thread ("fifo writer"), fifo (fifo_), buffer (buffer_) | |||||
| { | |||||
| startThread(); | |||||
| } | |||||
| ~WriteThread() | |||||
| { | |||||
| stopThread (5000); | |||||
| } | |||||
| void run() | |||||
| { | |||||
| int n = 0; | |||||
| while (! threadShouldExit()) | |||||
| { | |||||
| int num = Random::getSystemRandom().nextInt (2000) + 1; | |||||
| int start1, size1, start2, size2; | |||||
| fifo.prepareToWrite (num, start1, size1, start2, size2); | |||||
| jassert (size1 >= 0 && size2 >= 0); | |||||
| jassert (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())); | |||||
| jassert (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize())); | |||||
| int i; | |||||
| for (i = 0; i < size1; ++i) | |||||
| buffer [start1 + i] = n++; | |||||
| for (i = 0; i < size2; ++i) | |||||
| buffer [start2 + i] = n++; | |||||
| fifo.finishedWrite (size1 + size2); | |||||
| } | |||||
| } | |||||
| private: | |||||
| AbstractFifo& fifo; | |||||
| int* buffer; | |||||
| }; | |||||
| void runTest() | |||||
| { | |||||
| beginTest ("AbstractFifo"); | |||||
| int buffer [5000]; | |||||
| AbstractFifo fifo (numElementsInArray (buffer)); | |||||
| WriteThread writer (fifo, buffer); | |||||
| int n = 0; | |||||
| for (int count = 1000000; --count >= 0;) | |||||
| { | |||||
| int num = Random::getSystemRandom().nextInt (6000) + 1; | |||||
| int start1, size1, start2, size2; | |||||
| fifo.prepareToRead (num, start1, size1, start2, size2); | |||||
| if (! (size1 >= 0 && size2 >= 0) | |||||
| && (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize())) | |||||
| && (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize()))) | |||||
| { | |||||
| expect (false, "prepareToRead returned -ve values"); | |||||
| break; | |||||
| } | |||||
| bool failed = false; | |||||
| int i; | |||||
| for (i = 0; i < size1; ++i) | |||||
| failed = (buffer [start1 + i] != n++) || failed; | |||||
| for (i = 0; i < size2; ++i) | |||||
| failed = (buffer [start2 + i] != n++) || failed; | |||||
| if (failed) | |||||
| { | |||||
| expect (false, "read values were incorrect"); | |||||
| break; | |||||
| } | |||||
| fifo.finishedRead (size1 + size2); | |||||
| } | |||||
| } | |||||
| }; | |||||
| static AbstractFifoTests fifoUnitTests; | |||||
| #endif | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -74,7 +74,7 @@ namespace ComponentBuilderHelpers | |||||
| const ValueTree& state, Component* parent) | const ValueTree& state, Component* parent) | ||||
| { | { | ||||
| Component* const c = type.addNewComponentFromState (state, parent); | Component* const c = type.addNewComponentFromState (state, parent); | ||||
| jassert (c != 0); | |||||
| jassert (c != 0 && c->getParentComponent() == parent); | |||||
| c->setComponentID (getStateId (state)); | c->setComponentID (getStateId (state)); | ||||
| return c; | return c; | ||||
| } | } | ||||
| @@ -71,6 +71,8 @@ void RelativeCoordinatePositionerBase::ComponentScope::visitRelativeScope (const | |||||
| if (targetComp != 0) | if (targetComp != 0) | ||||
| visitor.visit (ComponentScope (*targetComp)); | visitor.visit (ComponentScope (*targetComp)); | ||||
| else | |||||
| Expression::Scope::visitRelativeScope (scopeName, visitor); | |||||
| } | } | ||||
| const String RelativeCoordinatePositionerBase::ComponentScope::getScopeUID() const | const String RelativeCoordinatePositionerBase::ComponentScope::getScopeUID() const | ||||
| @@ -175,6 +177,10 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| // The named component doesn't exist, so we'll watch the parent for changes in case it appears later.. | // The named component doesn't exist, so we'll watch the parent for changes in case it appears later.. | ||||
| Component* const parent = component.getParentComponent(); | |||||
| if (parent != 0) | |||||
| positioner.registerComponentListener (*parent); | |||||
| positioner.registerComponentListener (component); | positioner.registerComponentListener (component); | ||||
| ok = false; | ok = false; | ||||
| } | } | ||||
| @@ -208,10 +214,17 @@ void RelativeCoordinatePositionerBase::componentParentHierarchyChanged (Componen | |||||
| apply(); | apply(); | ||||
| } | } | ||||
| void RelativeCoordinatePositionerBase::componentChildrenChanged (Component& changed) | |||||
| { | |||||
| if (getComponent().getParentComponent() == &changed && ! registeredOk) | |||||
| apply(); | |||||
| } | |||||
| void RelativeCoordinatePositionerBase::componentBeingDeleted (Component& component) | void RelativeCoordinatePositionerBase::componentBeingDeleted (Component& component) | ||||
| { | { | ||||
| jassert (sourceComponents.contains (&component)); | jassert (sourceComponents.contains (&component)); | ||||
| sourceComponents.removeValue (&component); | sourceComponents.removeValue (&component); | ||||
| registeredOk = false; | |||||
| } | } | ||||
| void RelativeCoordinatePositionerBase::markersChanged (MarkerList*) | void RelativeCoordinatePositionerBase::markersChanged (MarkerList*) | ||||
| @@ -45,6 +45,7 @@ public: | |||||
| void componentMovedOrResized (Component&, bool, bool); | void componentMovedOrResized (Component&, bool, bool); | ||||
| void componentParentHierarchyChanged (Component&); | void componentParentHierarchyChanged (Component&); | ||||
| void componentChildrenChanged (Component& component); | |||||
| void componentBeingDeleted (Component& component); | void componentBeingDeleted (Component& component); | ||||
| void markersChanged (MarkerList*); | void markersChanged (MarkerList*); | ||||
| void markerListBeingDeleted (MarkerList* markerList); | void markerListBeingDeleted (MarkerList* markerList); | ||||
| @@ -337,7 +337,12 @@ public: | |||||
| visitor.useSymbol (Symbol (scope.getScopeUID(), getSymbol()->symbol)); | visitor.useSymbol (Symbol (scope.getScopeUID(), getSymbol()->symbol)); | ||||
| SymbolVisitingVisitor v (right, visitor, recursionDepth + 1); | SymbolVisitingVisitor v (right, visitor, recursionDepth + 1); | ||||
| scope.visitRelativeScope (getSymbol()->symbol, v); | |||||
| try | |||||
| { | |||||
| scope.visitRelativeScope (getSymbol()->symbol, v); | |||||
| } | |||||
| catch (...) {} | |||||
| } | } | ||||
| void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) | void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) | ||||
| @@ -346,7 +351,12 @@ public: | |||||
| getSymbol()->renameSymbol (oldSymbol, newName, scope, recursionDepth); | getSymbol()->renameSymbol (oldSymbol, newName, scope, recursionDepth); | ||||
| SymbolRenamingVisitor visitor (right, oldSymbol, newName, recursionDepth + 1); | SymbolRenamingVisitor visitor (right, oldSymbol, newName, recursionDepth + 1); | ||||
| scope.visitRelativeScope (getSymbol()->symbol, visitor); | |||||
| try | |||||
| { | |||||
| scope.visitRelativeScope (getSymbol()->symbol, visitor); | |||||
| } | |||||
| catch (...) {} | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -1196,8 +1206,9 @@ double Expression::Scope::evaluateFunction (const String& functionName, const do | |||||
| throw Helpers::EvaluationError ("Unknown function: \"" + functionName + "\""); | throw Helpers::EvaluationError ("Unknown function: \"" + functionName + "\""); | ||||
| } | } | ||||
| void Expression::Scope::visitRelativeScope (const String&, Visitor&) const | |||||
| void Expression::Scope::visitRelativeScope (const String& scopeName, Visitor&) const | |||||
| { | { | ||||
| throw Helpers::EvaluationError ("Unknown symbol: " + scopeName); | |||||
| } | } | ||||
| const String Expression::Scope::getScopeUID() const | const String Expression::Scope::getScopeUID() const | ||||