@@ -1600,35 +1600,12 @@ RelativeTime& RelativeTime::operator= (const RelativeTime& other) throw() | |||||
return *this; | return *this; | ||||
} | } | ||||
bool RelativeTime::operator== (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds == other.seconds; | |||||
} | |||||
bool RelativeTime::operator!= (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds != other.seconds; | |||||
} | |||||
bool RelativeTime::operator> (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds > other.seconds; | |||||
} | |||||
bool RelativeTime::operator< (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds < other.seconds; | |||||
} | |||||
bool RelativeTime::operator>= (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds >= other.seconds; | |||||
} | |||||
bool RelativeTime::operator<= (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds <= other.seconds; | |||||
} | |||||
bool RelativeTime::operator== (const RelativeTime& other) const throw() { return seconds == other.seconds; } | |||||
bool RelativeTime::operator!= (const RelativeTime& other) const throw() { return seconds != other.seconds; } | |||||
bool RelativeTime::operator> (const RelativeTime& other) const throw() { return seconds > other.seconds; } | |||||
bool RelativeTime::operator< (const RelativeTime& other) const throw() { return seconds < other.seconds; } | |||||
bool RelativeTime::operator>= (const RelativeTime& other) const throw() { return seconds >= other.seconds; } | |||||
bool RelativeTime::operator<= (const RelativeTime& other) const throw() { return seconds <= other.seconds; } | |||||
const RelativeTime RelativeTime::operator+ (const RelativeTime& timeToAdd) const throw() | const RelativeTime RelativeTime::operator+ (const RelativeTime& timeToAdd) const throw() | ||||
{ | { | ||||
@@ -4617,6 +4594,7 @@ public: | |||||
Constant (const double value_, bool isResolutionTarget_) | Constant (const double value_, bool isResolutionTarget_) | ||||
: value (value_), isResolutionTarget (isResolutionTarget_) {} | : value (value_), isResolutionTarget (isResolutionTarget_) {} | ||||
Type getType() const throw() { return constantType; } | |||||
Term* clone() const { return new Constant (value, isResolutionTarget); } | Term* clone() const { return new Constant (value, isResolutionTarget); } | ||||
double evaluate (const EvaluationContext&, int) const { return value; } | double evaluate (const EvaluationContext&, int) const { return value; } | ||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
@@ -4667,9 +4645,11 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Type getType() const throw() { return symbolType; } | |||||
Term* clone() const { return new Symbol (mainSymbol, member); } | Term* clone() const { return new Symbol (mainSymbol, member); } | ||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
Term* getInput (int) const { return 0; } | Term* getInput (int) const { return 0; } | ||||
const String getFunctionName() const { return toString(); } | |||||
const String toString() const | const String toString() const | ||||
{ | { | ||||
@@ -4716,9 +4696,11 @@ public: | |||||
return c.evaluateFunction (functionName, params, parameters.size()); | return c.evaluateFunction (functionName, params, parameters.size()); | ||||
} | } | ||||
int getInputIndexFor (const Term* possibleInput) const { return parameters.indexOf (possibleInput); } | |||||
int getNumInputs() const { return parameters.size(); } | |||||
Term* getInput (int i) const { return parameters [i]; } | |||||
Type getType() const throw() { return functionType; } | |||||
int getInputIndexFor (const Term* possibleInput) const { return parameters.indexOf (possibleInput); } | |||||
int getNumInputs() const { return parameters.size(); } | |||||
Term* getInput (int i) const { return parameters [i]; } | |||||
const String getFunctionName() const { return functionName; } | |||||
bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | ||||
{ | { | ||||
@@ -4760,11 +4742,13 @@ public: | |||||
jassert (input_ != 0); | jassert (input_ != 0); | ||||
} | } | ||||
Type getType() const throw() { return operatorType; } | |||||
int getInputIndexFor (const Term* possibleInput) const { return possibleInput == input ? 0 : -1; } | int getInputIndexFor (const Term* possibleInput) const { return possibleInput == input ? 0 : -1; } | ||||
int getNumInputs() const { return 1; } | int getNumInputs() const { return 1; } | ||||
Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (input) : 0; } | Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (input) : 0; } | ||||
Term* clone() const { return new Negate (input->clone()); } | Term* clone() const { return new Negate (input->clone()); } | ||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return -input->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return -input->evaluate (c, recursionDepth); } | ||||
const String getFunctionName() const { return "-"; } | |||||
const TermPtr negated() | const TermPtr negated() | ||||
{ | { | ||||
@@ -4811,6 +4795,8 @@ public: | |||||
return possibleInput == left ? 0 : (possibleInput == right ? 1 : -1); | return possibleInput == left ? 0 : (possibleInput == right ? 1 : -1); | ||||
} | } | ||||
Type getType() const throw() { return operatorType; } | |||||
int getNumInputs() const { return 2; } | int getNumInputs() const { return 2; } | ||||
Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (left) : (index == 1 ? static_cast<Term*> (right) : 0); } | Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (left) : (index == 1 ? static_cast<Term*> (right) : 0); } | ||||
@@ -4820,10 +4806,7 @@ public: | |||||
|| right->referencesSymbol (s, c, recursionDepth); | || right->referencesSymbol (s, c, recursionDepth); | ||||
} | } | ||||
protected: | |||||
const TermPtr left, right; | |||||
const String createString (const String& op) const | |||||
const String toString() const | |||||
{ | { | ||||
String s; | String s; | ||||
@@ -4833,7 +4816,7 @@ public: | |||||
else | else | ||||
s = left->toString(); | s = left->toString(); | ||||
s << ' ' << op << ' '; | |||||
s << ' ' << getFunctionName() << ' '; | |||||
if (right->getOperatorPrecedence() >= ourPrecendence) | if (right->getOperatorPrecedence() >= ourPrecendence) | ||||
s << '(' << right->toString() << ')'; | s << '(' << right->toString() << ')'; | ||||
@@ -4843,6 +4826,9 @@ public: | |||||
return s; | return s; | ||||
} | } | ||||
protected: | |||||
const TermPtr left, right; | |||||
const TermPtr createDestinationTerm (const EvaluationContext& context, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createDestinationTerm (const EvaluationContext& context, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
jassert (input == left || input == right); | jassert (input == left || input == right); | ||||
@@ -4863,10 +4849,10 @@ public: | |||||
public: | public: | ||||
Add (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Add (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Add (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Add (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) + right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) + right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("+"); } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
const String getFunctionName() const { return "+"; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -4883,10 +4869,10 @@ public: | |||||
public: | public: | ||||
Subtract (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Subtract (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Subtract (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Subtract (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) - right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) - right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("-"); } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
const String getFunctionName() const { return "-"; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -4906,10 +4892,10 @@ public: | |||||
public: | public: | ||||
Multiply (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Multiply (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Multiply (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Multiply (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) * right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) * right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("*"); } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const String getFunctionName() const { return "*"; } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -4926,10 +4912,10 @@ public: | |||||
public: | public: | ||||
Divide (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Divide (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Divide (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Divide (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) / right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) / right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("/"); } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const String getFunctionName() const { return "/"; } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -5444,6 +5430,36 @@ bool Expression::usesAnySymbols() const | |||||
return Helpers::containsAnySymbols (term); | return Helpers::containsAnySymbols (term); | ||||
} | } | ||||
Expression::Type Expression::getType() const throw() | |||||
{ | |||||
return term->getType(); | |||||
} | |||||
const String Expression::getSymbol() const | |||||
{ | |||||
return term->getSymbolName(); | |||||
} | |||||
const String Expression::getFunction() const | |||||
{ | |||||
return term->getFunctionName(); | |||||
} | |||||
const String Expression::getOperator() const | |||||
{ | |||||
return term->getFunctionName(); | |||||
} | |||||
int Expression::getNumInputs() const | |||||
{ | |||||
return term->getNumInputs(); | |||||
} | |||||
const Expression Expression::getInput (int index) const | |||||
{ | |||||
return Expression (term->getInput (index)); | |||||
} | |||||
int Expression::Term::getOperatorPrecedence() const | int Expression::Term::getOperatorPrecedence() const | ||||
{ | { | ||||
return 0; | return 0; | ||||
@@ -5470,6 +5486,18 @@ const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::negated() | |||||
return new Helpers::Negate (this); | return new Helpers::Negate (this); | ||||
} | } | ||||
const String Expression::Term::getSymbolName() const | |||||
{ | |||||
jassertfalse; // You should only call getSymbol() on an expression that's actually a symbol! | |||||
return String::empty; | |||||
} | |||||
const String Expression::Term::getFunctionName() const | |||||
{ | |||||
jassertfalse; // You shouldn't call this for an expression that's not actually a function! | |||||
return String::empty; | |||||
} | |||||
Expression::ParseError::ParseError (const String& message) | Expression::ParseError::ParseError (const String& message) | ||||
: description (message) | : description (message) | ||||
{ | { | ||||
@@ -276206,6 +276234,16 @@ public: | |||||
if (JUCEApplication::getInstance() != 0) | if (JUCEApplication::getInstance() != 0) | ||||
{ | { | ||||
JUCEApplication::getInstance()->systemRequestedQuit(); | JUCEApplication::getInstance()->systemRequestedQuit(); | ||||
if (MessageManager::getInstance()->hasStopMessageBeenSent()) | |||||
{ | |||||
[NSApp performSelectorOnMainThread: @selector (replyToApplicationShouldTerminate:) | |||||
withObject: [NSNumber numberWithBool: YES] | |||||
waitUntilDone: NO]; | |||||
return NSTerminateLater; | |||||
} | |||||
return NSTerminateCancel; | return NSTerminateCancel; | ||||
} | } | ||||
@@ -64,7 +64,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 58 | |||||
#define JUCE_BUILDNUMBER 59 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -6651,11 +6651,13 @@ public: | |||||
/** Evaluates this expression, without using an EvaluationContext. | /** Evaluates this expression, without using an EvaluationContext. | ||||
Without an EvaluationContext, no symbols can be used, and only basic functions such as sin, cos, tan, | Without an EvaluationContext, no symbols can be used, and only basic functions such as sin, cos, tan, | ||||
min, max are available. | min, max are available. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
double evaluate() const; | double evaluate() const; | ||||
/** Evaluates this expression, providing a context that should be able to evaluate any symbols | /** Evaluates this expression, providing a context that should be able to evaluate any symbols | ||||
or functions that it uses. | or functions that it uses. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
double evaluate (const EvaluationContext& context) const; | double evaluate (const EvaluationContext& context) const; | ||||
@@ -6665,6 +6667,8 @@ public: | |||||
E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | ||||
the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | ||||
case they might just be adjusted by adding a constant to them. | case they might just be adjusted by adding a constant to them. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
const Expression adjustedToGiveNewResult (double targetValue, const EvaluationContext& context) const; | const Expression adjustedToGiveNewResult (double targetValue, const EvaluationContext& context) const; | ||||
@@ -6675,6 +6679,8 @@ public: | |||||
If a suitable context is supplied, the search will dereference and recursively check | If a suitable context is supplied, the search will dereference and recursively check | ||||
all symbols, so that it can be determined whether this expression relies on the given | all symbols, so that it can be determined whether this expression relies on the given | ||||
symbol at any level in its evaluation. | symbol at any level in its evaluation. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
bool referencesSymbol (const String& symbol, const EvaluationContext& context) const; | bool referencesSymbol (const String& symbol, const EvaluationContext& context) const; | ||||
@@ -6699,6 +6705,41 @@ public: | |||||
String description; | String description; | ||||
}; | }; | ||||
/** Expression type. | |||||
@see Expression::getType() | |||||
*/ | |||||
enum Type | |||||
{ | |||||
constantType, | |||||
functionType, | |||||
operatorType, | |||||
symbolType | |||||
}; | |||||
/** Returns the type of this expression. */ | |||||
Type getType() const throw(); | |||||
/** If this expression is a symbol, this returns its name. */ | |||||
const String getSymbol() const; | |||||
/** If this expression is a function, this returns its name. */ | |||||
const String getFunction() const; | |||||
/** If this expression is an operator, this returns its name. | |||||
E.g. "+", "-", "*", "/", etc. | |||||
*/ | |||||
const String getOperator() const; | |||||
/** Returns the number of inputs to this expression. | |||||
@see getInput | |||||
*/ | |||||
int getNumInputs() const; | |||||
/** Retrieves one of the inputs to this expression. | |||||
@see getNumInputs | |||||
*/ | |||||
const Expression getInput (int index) const; | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
@@ -6722,6 +6763,10 @@ private: | |||||
virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, const Term* inputTerm, | virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, const Term* inputTerm, | ||||
double overallTarget, Term* topLevelTerm) const; | double overallTarget, Term* topLevelTerm) const; | ||||
virtual const ReferenceCountedObjectPtr<Term> negated(); | virtual const ReferenceCountedObjectPtr<Term> negated(); | ||||
virtual Type getType() const throw() = 0; | |||||
virtual const String getSymbolName() const; | |||||
virtual const String getFunctionName() const; | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
@@ -44,6 +44,7 @@ public: | |||||
Constant (const double value_, bool isResolutionTarget_) | Constant (const double value_, bool isResolutionTarget_) | ||||
: value (value_), isResolutionTarget (isResolutionTarget_) {} | : value (value_), isResolutionTarget (isResolutionTarget_) {} | ||||
Type getType() const throw() { return constantType; } | |||||
Term* clone() const { return new Constant (value, isResolutionTarget); } | Term* clone() const { return new Constant (value, isResolutionTarget); } | ||||
double evaluate (const EvaluationContext&, int) const { return value; } | double evaluate (const EvaluationContext&, int) const { return value; } | ||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
@@ -95,9 +96,11 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Type getType() const throw() { return symbolType; } | |||||
Term* clone() const { return new Symbol (mainSymbol, member); } | Term* clone() const { return new Symbol (mainSymbol, member); } | ||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
Term* getInput (int) const { return 0; } | Term* getInput (int) const { return 0; } | ||||
const String getFunctionName() const { return toString(); } | |||||
const String toString() const | const String toString() const | ||||
{ | { | ||||
@@ -145,9 +148,11 @@ public: | |||||
return c.evaluateFunction (functionName, params, parameters.size()); | return c.evaluateFunction (functionName, params, parameters.size()); | ||||
} | } | ||||
int getInputIndexFor (const Term* possibleInput) const { return parameters.indexOf (possibleInput); } | |||||
int getNumInputs() const { return parameters.size(); } | |||||
Term* getInput (int i) const { return parameters [i]; } | |||||
Type getType() const throw() { return functionType; } | |||||
int getInputIndexFor (const Term* possibleInput) const { return parameters.indexOf (possibleInput); } | |||||
int getNumInputs() const { return parameters.size(); } | |||||
Term* getInput (int i) const { return parameters [i]; } | |||||
const String getFunctionName() const { return functionName; } | |||||
bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | bool referencesSymbol (const String& s, const EvaluationContext& c, int recursionDepth) const | ||||
{ | { | ||||
@@ -190,11 +195,13 @@ public: | |||||
jassert (input_ != 0); | jassert (input_ != 0); | ||||
} | } | ||||
Type getType() const throw() { return operatorType; } | |||||
int getInputIndexFor (const Term* possibleInput) const { return possibleInput == input ? 0 : -1; } | int getInputIndexFor (const Term* possibleInput) const { return possibleInput == input ? 0 : -1; } | ||||
int getNumInputs() const { return 1; } | int getNumInputs() const { return 1; } | ||||
Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (input) : 0; } | Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (input) : 0; } | ||||
Term* clone() const { return new Negate (input->clone()); } | Term* clone() const { return new Negate (input->clone()); } | ||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return -input->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return -input->evaluate (c, recursionDepth); } | ||||
const String getFunctionName() const { return "-"; } | |||||
const TermPtr negated() | const TermPtr negated() | ||||
{ | { | ||||
@@ -242,6 +249,8 @@ public: | |||||
return possibleInput == left ? 0 : (possibleInput == right ? 1 : -1); | return possibleInput == left ? 0 : (possibleInput == right ? 1 : -1); | ||||
} | } | ||||
Type getType() const throw() { return operatorType; } | |||||
int getNumInputs() const { return 2; } | int getNumInputs() const { return 2; } | ||||
Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (left) : (index == 1 ? static_cast<Term*> (right) : 0); } | Term* getInput (int index) const { return index == 0 ? static_cast<Term*> (left) : (index == 1 ? static_cast<Term*> (right) : 0); } | ||||
@@ -251,10 +260,7 @@ public: | |||||
|| right->referencesSymbol (s, c, recursionDepth); | || right->referencesSymbol (s, c, recursionDepth); | ||||
} | } | ||||
protected: | |||||
const TermPtr left, right; | |||||
const String createString (const String& op) const | |||||
const String toString() const | |||||
{ | { | ||||
String s; | String s; | ||||
@@ -264,7 +270,7 @@ public: | |||||
else | else | ||||
s = left->toString(); | s = left->toString(); | ||||
s << ' ' << op << ' '; | |||||
s << ' ' << getFunctionName() << ' '; | |||||
if (right->getOperatorPrecedence() >= ourPrecendence) | if (right->getOperatorPrecedence() >= ourPrecendence) | ||||
s << '(' << right->toString() << ')'; | s << '(' << right->toString() << ')'; | ||||
@@ -274,6 +280,9 @@ public: | |||||
return s; | return s; | ||||
} | } | ||||
protected: | |||||
const TermPtr left, right; | |||||
const TermPtr createDestinationTerm (const EvaluationContext& context, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createDestinationTerm (const EvaluationContext& context, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
jassert (input == left || input == right); | jassert (input == left || input == right); | ||||
@@ -295,10 +304,10 @@ public: | |||||
public: | public: | ||||
Add (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Add (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Add (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Add (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) + right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) + right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("+"); } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
const String getFunctionName() const { return "+"; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -316,10 +325,10 @@ public: | |||||
public: | public: | ||||
Subtract (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Subtract (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Subtract (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Subtract (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) - right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) - right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("-"); } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
int getOperatorPrecedence() const { return 2; } | |||||
const String getFunctionName() const { return "-"; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -340,10 +349,10 @@ public: | |||||
public: | public: | ||||
Multiply (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Multiply (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Multiply (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Multiply (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) * right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) * right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("*"); } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const String getFunctionName() const { return "*"; } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -361,10 +370,10 @@ public: | |||||
public: | public: | ||||
Divide (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | Divide (Term* const left_, Term* const right_) : BinaryTerm (left_, right_) {} | ||||
Term* clone() const { return new Divide (left->clone(), right->clone()); } | |||||
Term* clone() const { return new Divide (left->clone(), right->clone()); } | |||||
double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) / right->evaluate (c, recursionDepth); } | double evaluate (const EvaluationContext& c, int recursionDepth) const { return left->evaluate (c, recursionDepth) / right->evaluate (c, recursionDepth); } | ||||
const String toString() const { return createString ("/"); } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const String getFunctionName() const { return "/"; } | |||||
int getOperatorPrecedence() const { return 1; } | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | ||||
{ | { | ||||
@@ -883,6 +892,36 @@ bool Expression::usesAnySymbols() const | |||||
return Helpers::containsAnySymbols (term); | return Helpers::containsAnySymbols (term); | ||||
} | } | ||||
Expression::Type Expression::getType() const throw() | |||||
{ | |||||
return term->getType(); | |||||
} | |||||
const String Expression::getSymbol() const | |||||
{ | |||||
return term->getSymbolName(); | |||||
} | |||||
const String Expression::getFunction() const | |||||
{ | |||||
return term->getFunctionName(); | |||||
} | |||||
const String Expression::getOperator() const | |||||
{ | |||||
return term->getFunctionName(); | |||||
} | |||||
int Expression::getNumInputs() const | |||||
{ | |||||
return term->getNumInputs(); | |||||
} | |||||
const Expression Expression::getInput (int index) const | |||||
{ | |||||
return Expression (term->getInput (index)); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
int Expression::Term::getOperatorPrecedence() const | int Expression::Term::getOperatorPrecedence() const | ||||
{ | { | ||||
@@ -910,6 +949,18 @@ const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::negated() | |||||
return new Helpers::Negate (this); | return new Helpers::Negate (this); | ||||
} | } | ||||
const String Expression::Term::getSymbolName() const | |||||
{ | |||||
jassertfalse; // You should only call getSymbol() on an expression that's actually a symbol! | |||||
return String::empty; | |||||
} | |||||
const String Expression::Term::getFunctionName() const | |||||
{ | |||||
jassertfalse; // You shouldn't call this for an expression that's not actually a function! | |||||
return String::empty; | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
Expression::ParseError::ParseError (const String& message) | Expression::ParseError::ParseError (const String& message) | ||||
: description (message) | : description (message) | ||||
@@ -129,11 +129,13 @@ public: | |||||
/** Evaluates this expression, without using an EvaluationContext. | /** Evaluates this expression, without using an EvaluationContext. | ||||
Without an EvaluationContext, no symbols can be used, and only basic functions such as sin, cos, tan, | Without an EvaluationContext, no symbols can be used, and only basic functions such as sin, cos, tan, | ||||
min, max are available. | min, max are available. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
double evaluate() const; | double evaluate() const; | ||||
/** Evaluates this expression, providing a context that should be able to evaluate any symbols | /** Evaluates this expression, providing a context that should be able to evaluate any symbols | ||||
or functions that it uses. | or functions that it uses. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
double evaluate (const EvaluationContext& context) const; | double evaluate (const EvaluationContext& context) const; | ||||
@@ -143,6 +145,8 @@ public: | |||||
E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | ||||
the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | ||||
case they might just be adjusted by adding a constant to them. | case they might just be adjusted by adding a constant to them. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
const Expression adjustedToGiveNewResult (double targetValue, const EvaluationContext& context) const; | const Expression adjustedToGiveNewResult (double targetValue, const EvaluationContext& context) const; | ||||
@@ -153,6 +157,8 @@ public: | |||||
If a suitable context is supplied, the search will dereference and recursively check | If a suitable context is supplied, the search will dereference and recursively check | ||||
all symbols, so that it can be determined whether this expression relies on the given | all symbols, so that it can be determined whether this expression relies on the given | ||||
symbol at any level in its evaluation. | symbol at any level in its evaluation. | ||||
@throws Expression::EvaluationError | |||||
*/ | */ | ||||
bool referencesSymbol (const String& symbol, const EvaluationContext& context) const; | bool referencesSymbol (const String& symbol, const EvaluationContext& context) const; | ||||
@@ -179,6 +185,42 @@ public: | |||||
String description; | String description; | ||||
}; | }; | ||||
//============================================================================== | |||||
/** Expression type. | |||||
@see Expression::getType() | |||||
*/ | |||||
enum Type | |||||
{ | |||||
constantType, | |||||
functionType, | |||||
operatorType, | |||||
symbolType | |||||
}; | |||||
/** Returns the type of this expression. */ | |||||
Type getType() const throw(); | |||||
/** If this expression is a symbol, this returns its name. */ | |||||
const String getSymbol() const; | |||||
/** If this expression is a function, this returns its name. */ | |||||
const String getFunction() const; | |||||
/** If this expression is an operator, this returns its name. | |||||
E.g. "+", "-", "*", "/", etc. | |||||
*/ | |||||
const String getOperator() const; | |||||
/** Returns the number of inputs to this expression. | |||||
@see getInput | |||||
*/ | |||||
int getNumInputs() const; | |||||
/** Retrieves one of the inputs to this expression. | |||||
@see getNumInputs | |||||
*/ | |||||
const Expression getInput (int index) const; | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -203,6 +245,10 @@ private: | |||||
virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, const Term* inputTerm, | virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, const Term* inputTerm, | ||||
double overallTarget, Term* topLevelTerm) const; | double overallTarget, Term* topLevelTerm) const; | ||||
virtual const ReferenceCountedObjectPtr<Term> negated(); | virtual const ReferenceCountedObjectPtr<Term> negated(); | ||||
virtual Type getType() const throw() = 0; | |||||
virtual const String getSymbolName() const; | |||||
virtual const String getFunctionName() const; | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
@@ -183,35 +183,12 @@ RelativeTime& RelativeTime::operator= (const RelativeTime& other) throw() | |||||
return *this; | return *this; | ||||
} | } | ||||
bool RelativeTime::operator== (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds == other.seconds; | |||||
} | |||||
bool RelativeTime::operator!= (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds != other.seconds; | |||||
} | |||||
bool RelativeTime::operator> (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds > other.seconds; | |||||
} | |||||
bool RelativeTime::operator< (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds < other.seconds; | |||||
} | |||||
bool RelativeTime::operator>= (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds >= other.seconds; | |||||
} | |||||
bool RelativeTime::operator<= (const RelativeTime& other) const throw() | |||||
{ | |||||
return seconds <= other.seconds; | |||||
} | |||||
bool RelativeTime::operator== (const RelativeTime& other) const throw() { return seconds == other.seconds; } | |||||
bool RelativeTime::operator!= (const RelativeTime& other) const throw() { return seconds != other.seconds; } | |||||
bool RelativeTime::operator> (const RelativeTime& other) const throw() { return seconds > other.seconds; } | |||||
bool RelativeTime::operator< (const RelativeTime& other) const throw() { return seconds < other.seconds; } | |||||
bool RelativeTime::operator>= (const RelativeTime& other) const throw() { return seconds >= other.seconds; } | |||||
bool RelativeTime::operator<= (const RelativeTime& other) const throw() { return seconds <= other.seconds; } | |||||
//============================================================================== | //============================================================================== | ||||
const RelativeTime RelativeTime::operator+ (const RelativeTime& timeToAdd) const throw() | const RelativeTime RelativeTime::operator+ (const RelativeTime& timeToAdd) const throw() | ||||
@@ -33,7 +33,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 58 | |||||
#define JUCE_BUILDNUMBER 59 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -69,6 +69,16 @@ public: | |||||
if (JUCEApplication::getInstance() != 0) | if (JUCEApplication::getInstance() != 0) | ||||
{ | { | ||||
JUCEApplication::getInstance()->systemRequestedQuit(); | JUCEApplication::getInstance()->systemRequestedQuit(); | ||||
if (MessageManager::getInstance()->hasStopMessageBeenSent()) | |||||
{ | |||||
[NSApp performSelectorOnMainThread: @selector (replyToApplicationShouldTerminate:) | |||||
withObject: [NSNumber numberWithBool: YES] | |||||
waitUntilDone: NO]; | |||||
return NSTerminateLater; | |||||
} | |||||
return NSTerminateCancel; | return NSTerminateCancel; | ||||
} | } | ||||