@@ -352,10 +352,10 @@ const Expression RelativeRectangleLayoutManager::getSymbolValue (const String& s | |||||
if (c->name == objectName) | if (c->name == objectName) | ||||
{ | { | ||||
if (edge == RelativeCoordinate::Strings::left) return c->coords.left.getTerm(); | |||||
if (edge == RelativeCoordinate::Strings::right) return c->coords.right.getTerm(); | |||||
if (edge == RelativeCoordinate::Strings::top) return c->coords.top.getTerm(); | |||||
if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom.getTerm(); | |||||
if (edge == RelativeCoordinate::Strings::left) return c->coords.left.getExpression(); | |||||
if (edge == RelativeCoordinate::Strings::right) return c->coords.right.getExpression(); | |||||
if (edge == RelativeCoordinate::Strings::top) return c->coords.top.getExpression(); | |||||
if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom.getExpression(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -365,7 +365,7 @@ const Expression RelativeRectangleLayoutManager::getSymbolValue (const String& s | |||||
MarkerPosition* m = markers.getUnchecked(i); | MarkerPosition* m = markers.getUnchecked(i); | ||||
if (m->markerName == objectName) | if (m->markerName == objectName) | ||||
return m->position.getTerm(); | |||||
return m->position.getExpression(); | |||||
} | } | ||||
return Expression(); | return Expression(); | ||||
@@ -4599,6 +4599,7 @@ BEGIN_JUCE_NAMESPACE | |||||
class Expression::Helpers | class Expression::Helpers | ||||
{ | { | ||||
public: | public: | ||||
typedef ReferenceCountedObjectPtr<Term> TermPtr; | |||||
class Constant : public Term | class Constant : public Term | ||||
{ | { | ||||
@@ -4610,6 +4611,11 @@ public: | |||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
Term* getInput (int) const { return 0; } | Term* getInput (int) const { return 0; } | ||||
const TermPtr negated() | |||||
{ | |||||
return new Constant (-value); | |||||
} | |||||
const String toString() const | const String toString() const | ||||
{ | { | ||||
if (isResolutionTarget) | if (isResolutionTarget) | ||||
@@ -4632,7 +4638,14 @@ public: | |||||
if (++recursionDepth > 256) | if (++recursionDepth > 256) | ||||
throw EvaluationError ("Recursive symbol references"); | throw EvaluationError ("Recursive symbol references"); | ||||
return c.getSymbolValue (symbol).term->evaluate (c, recursionDepth); | |||||
try | |||||
{ | |||||
return c.getSymbolValue (symbol).term->evaluate (c, recursionDepth); | |||||
} | |||||
catch (...) | |||||
{} | |||||
return 0; | |||||
} | } | ||||
Term* clone() const { return new Symbol (symbol); } | Term* clone() const { return new Symbol (symbol); } | ||||
@@ -4711,7 +4724,7 @@ public: | |||||
class Negate : public Term | class Negate : public Term | ||||
{ | { | ||||
public: | public: | ||||
Negate (Term* const input_) : input (input_) | |||||
Negate (const TermPtr& input_) : input (input_) | |||||
{ | { | ||||
jassert (input_ != 0); | jassert (input_ != 0); | ||||
} | } | ||||
@@ -4722,18 +4735,19 @@ public: | |||||
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 ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, Term* input_, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr negated() | |||||
{ | |||||
return input; | |||||
} | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& context, const Term* input_, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
jassert (input_ == input); | jassert (input_ == input); | ||||
const Term* const dest = findDestinationFor (topLevelTerm, this); | const Term* const dest = findDestinationFor (topLevelTerm, this); | ||||
Term* newDest; | |||||
if (dest == 0) | |||||
newDest = new Constant (overallTarget); | |||||
else | |||||
newDest = dest->clone(); | |||||
return new Negate (newDest); | |||||
return new Negate (dest == 0 ? new Constant (overallTarget) | |||||
: dest->createTermToEvaluateInput (context, this, overallTarget, topLevelTerm)); | |||||
} | } | ||||
const String toString() const | const String toString() const | ||||
@@ -4750,7 +4764,7 @@ public: | |||||
} | } | ||||
private: | private: | ||||
const ReferenceCountedObjectPtr<Term> input; | |||||
const TermPtr input; | |||||
}; | }; | ||||
class BinaryTerm : public Term | class BinaryTerm : public Term | ||||
@@ -4776,7 +4790,7 @@ public: | |||||
} | } | ||||
protected: | protected: | ||||
const ReferenceCountedObjectPtr<Term> left, right; | |||||
const TermPtr left, right; | |||||
const String createString (const String& op) const | const String createString (const String& op) const | ||||
{ | { | ||||
@@ -4798,7 +4812,7 @@ public: | |||||
return s; | return s; | ||||
} | } | ||||
Term* createDestinationTerm (const EvaluationContext&, 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); | ||||
if (input != left && input != right) | if (input != left && input != right) | ||||
@@ -4809,7 +4823,7 @@ public: | |||||
if (dest == 0) | if (dest == 0) | ||||
return new Constant (overallTarget); | return new Constant (overallTarget); | ||||
return dest->clone(); | |||||
return dest->createTermToEvaluateInput (context, this, overallTarget, topLevelTerm); | |||||
} | } | ||||
}; | }; | ||||
@@ -4823,9 +4837,9 @@ public: | |||||
const String toString() const { return createString ("+"); } | const String toString() const { return createString ("+"); } | ||||
int getOperatorPrecedence() const { return 2; } | int getOperatorPrecedence() const { return 2; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -4843,9 +4857,9 @@ public: | |||||
const String toString() const { return createString ("-"); } | const String toString() const { return createString ("-"); } | ||||
int getOperatorPrecedence() const { return 2; } | int getOperatorPrecedence() const { return 2; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -4866,9 +4880,9 @@ public: | |||||
const String toString() const { return createString ("*"); } | const String toString() const { return createString ("*"); } | ||||
int getOperatorPrecedence() const { return 1; } | int getOperatorPrecedence() const { return 1; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -4886,9 +4900,9 @@ public: | |||||
const String toString() const { return createString ("/"); } | const String toString() const { return createString ("/"); } | ||||
int getOperatorPrecedence() const { return 1; } | int getOperatorPrecedence() const { return 1; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -4989,25 +5003,25 @@ public: | |||||
text = textString; | text = textString; | ||||
} | } | ||||
Term* readExpression() | |||||
const TermPtr readExpression() | |||||
{ | { | ||||
ScopedPointer<Term> lhs (readMultiplyOrDivideExpression()); | |||||
TermPtr lhs (readMultiplyOrDivideExpression()); | |||||
char opType; | char opType; | ||||
while (lhs != 0 && readOperator ("+-", &opType)) | while (lhs != 0 && readOperator ("+-", &opType)) | ||||
{ | { | ||||
Term* rhs = readMultiplyOrDivideExpression(); | |||||
TermPtr rhs (readMultiplyOrDivideExpression()); | |||||
if (rhs == 0) | if (rhs == 0) | ||||
throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | ||||
if (opType == '+') | if (opType == '+') | ||||
lhs = new Add (lhs.release(), rhs); | |||||
lhs = new Add (lhs, rhs); | |||||
else | else | ||||
lhs = new Subtract (lhs.release(), rhs); | |||||
lhs = new Subtract (lhs, rhs); | |||||
} | } | ||||
return lhs.release(); | |||||
return lhs; | |||||
} | } | ||||
private: | private: | ||||
@@ -5143,39 +5157,39 @@ public: | |||||
return t; | return t; | ||||
} | } | ||||
Term* readMultiplyOrDivideExpression() | |||||
const TermPtr readMultiplyOrDivideExpression() | |||||
{ | { | ||||
ScopedPointer<Term> lhs (readUnaryExpression()); | |||||
TermPtr lhs (readUnaryExpression()); | |||||
char opType; | char opType; | ||||
while (lhs != 0 && readOperator ("*/", &opType)) | while (lhs != 0 && readOperator ("*/", &opType)) | ||||
{ | { | ||||
Term* rhs = readUnaryExpression(); | |||||
TermPtr rhs (readUnaryExpression()); | |||||
if (rhs == 0) | if (rhs == 0) | ||||
throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | ||||
if (opType == '*') | if (opType == '*') | ||||
lhs = new Multiply (lhs.release(), rhs); | |||||
lhs = new Multiply (lhs, rhs); | |||||
else | else | ||||
lhs = new Divide (lhs.release(), rhs); | |||||
lhs = new Divide (lhs, rhs); | |||||
} | } | ||||
return lhs.release(); | |||||
return lhs; | |||||
} | } | ||||
Term* readUnaryExpression() | |||||
const TermPtr readUnaryExpression() | |||||
{ | { | ||||
char opType; | char opType; | ||||
if (readOperator ("+-", &opType)) | if (readOperator ("+-", &opType)) | ||||
{ | { | ||||
Term* term = readUnaryExpression(); | |||||
TermPtr term (readUnaryExpression()); | |||||
if (term == 0) | if (term == 0) | ||||
throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | ||||
if (opType == '-') | if (opType == '-') | ||||
term = new Negate (term); | |||||
term = term->negated(); | |||||
return term; | return term; | ||||
} | } | ||||
@@ -5183,9 +5197,9 @@ public: | |||||
return readPrimaryExpression(); | return readPrimaryExpression(); | ||||
} | } | ||||
Term* readPrimaryExpression() | |||||
const TermPtr readPrimaryExpression() | |||||
{ | { | ||||
Term* e = readParenthesisedExpression(); | |||||
TermPtr e (readParenthesisedExpression()); | |||||
if (e != 0) | if (e != 0) | ||||
return e; | return e; | ||||
@@ -5201,7 +5215,7 @@ public: | |||||
Function* f = new Function (identifier, ReferenceCountedArray<Term>()); | Function* f = new Function (identifier, ReferenceCountedArray<Term>()); | ||||
ScopedPointer<Term> func (f); // (can't use ScopedPointer<Function> in MSVC) | ScopedPointer<Term> func (f); // (can't use ScopedPointer<Function> in MSVC) | ||||
Term* param = readExpression(); | |||||
TermPtr param (readExpression()); | |||||
if (param == 0) | if (param == 0) | ||||
{ | { | ||||
@@ -5237,19 +5251,16 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Term* readParenthesisedExpression() | |||||
const TermPtr readParenthesisedExpression() | |||||
{ | { | ||||
if (! readOperator ("(")) | if (! readOperator ("(")) | ||||
return 0; | return 0; | ||||
ScopedPointer<Term> e (readExpression()); | |||||
if (e == 0) | |||||
const TermPtr e (readExpression()); | |||||
if (e == 0 || ! readOperator (")")) | |||||
return 0; | return 0; | ||||
if (! readOperator (")")) | |||||
e = 0; | |||||
return e.release(); | |||||
return e; | |||||
} | } | ||||
Parser (const Parser&); | Parser (const Parser&); | ||||
@@ -5301,7 +5312,7 @@ Expression::Expression (const String& stringToParse) | |||||
const Expression Expression::parse (const String& stringToParse, int& textIndexToStartFrom) | const Expression Expression::parse (const String& stringToParse, int& textIndexToStartFrom) | ||||
{ | { | ||||
Helpers::Parser parser (stringToParse, textIndexToStartFrom); | Helpers::Parser parser (stringToParse, textIndexToStartFrom); | ||||
Term* term = parser.readExpression(); | |||||
const Helpers::TermPtr term (parser.readExpression()); | |||||
if (term != 0) | if (term != 0) | ||||
return Expression (term); | return Expression (term); | ||||
@@ -5341,7 +5352,7 @@ const Expression Expression::operator/ (const Expression& other) const | |||||
const Expression Expression::operator-() const | const Expression Expression::operator-() const | ||||
{ | { | ||||
return Expression (new Helpers::Negate (term)); | |||||
return Expression (term->negated()); | |||||
} | } | ||||
const String Expression::toString() const | const String Expression::toString() const | ||||
@@ -5389,7 +5400,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
const ReferenceCountedObjectPtr<Term> reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | |||||
const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | |||||
if (reverseTerm == 0) | if (reverseTerm == 0) | ||||
return Expression(); | return Expression(); | ||||
@@ -5434,20 +5445,27 @@ int Expression::Term::getInputIndexFor (const Term*) const | |||||
return -1; | return -1; | ||||
} | } | ||||
const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::createTermToEvaluateInput (const EvaluationContext&, Term*, double, Term*) const | |||||
const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::createTermToEvaluateInput (const EvaluationContext&, const Term*, double, Term*) const | |||||
{ | { | ||||
jassertfalse; | jassertfalse; | ||||
return 0; | return 0; | ||||
} | } | ||||
const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::negated() | |||||
{ | |||||
return new Helpers::Negate (this); | |||||
} | |||||
Expression::ParseError::ParseError (const String& message) | Expression::ParseError::ParseError (const String& message) | ||||
: description (message) | : description (message) | ||||
{ | { | ||||
DBG ("Expression::ParseError: " + message); | |||||
} | } | ||||
Expression::EvaluationError::EvaluationError (const String& message) | Expression::EvaluationError::EvaluationError (const String& message) | ||||
: description (message) | : description (message) | ||||
{ | { | ||||
DBG ("Expression::EvaluationError: " + message); | |||||
} | } | ||||
Expression::EvaluationContext::EvaluationContext() {} | Expression::EvaluationContext::EvaluationContext() {} | ||||
@@ -79820,7 +79838,7 @@ const String RelativeCoordinate::toString() const | |||||
void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | ||||
const Expression::EvaluationContext* context) | const Expression::EvaluationContext* context) | ||||
{ | { | ||||
jassert (newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
if (term.referencesSymbol (oldName, *context)) | if (term.referencesSymbol (oldName, *context)) | ||||
{ | { | ||||
@@ -79908,9 +79926,9 @@ RelativeRectangle::RelativeRectangle (const RelativeCoordinate& left_, const Rel | |||||
RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect, const String& componentName) | RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect, const String& componentName) | ||||
: left (rect.getX()), | : left (rect.getX()), | ||||
right (componentName + "." + RelativeCoordinate::Strings::left + " + " + String (rect.getWidth())), | |||||
right (Expression::symbol (componentName + "." + RelativeCoordinate::Strings::left) + Expression ((double) rect.getWidth())), | |||||
top (rect.getY()), | top (rect.getY()), | ||||
bottom (componentName + "." + RelativeCoordinate::Strings::top + " + " + String (rect.getHeight())) | |||||
bottom (Expression::symbol (componentName + "." + RelativeCoordinate::Strings::top) + Expression ((double) rect.getHeight())) | |||||
{ | { | ||||
} | } | ||||
@@ -237900,18 +237918,12 @@ bool juce_setThreadPriority (void* threadHandle, int priority) | |||||
{ | { | ||||
int pri = THREAD_PRIORITY_TIME_CRITICAL; | int pri = THREAD_PRIORITY_TIME_CRITICAL; | ||||
if (priority < 1) | |||||
pri = THREAD_PRIORITY_IDLE; | |||||
else if (priority < 2) | |||||
pri = THREAD_PRIORITY_LOWEST; | |||||
else if (priority < 5) | |||||
pri = THREAD_PRIORITY_BELOW_NORMAL; | |||||
else if (priority < 7) | |||||
pri = THREAD_PRIORITY_NORMAL; | |||||
else if (priority < 9) | |||||
pri = THREAD_PRIORITY_ABOVE_NORMAL; | |||||
else if (priority < 10) | |||||
pri = THREAD_PRIORITY_HIGHEST; | |||||
if (priority < 1) pri = THREAD_PRIORITY_IDLE; | |||||
else if (priority < 2) pri = THREAD_PRIORITY_LOWEST; | |||||
else if (priority < 5) pri = THREAD_PRIORITY_BELOW_NORMAL; | |||||
else if (priority < 7) pri = THREAD_PRIORITY_NORMAL; | |||||
else if (priority < 9) pri = THREAD_PRIORITY_ABOVE_NORMAL; | |||||
else if (priority < 10) pri = THREAD_PRIORITY_HIGHEST; | |||||
if (threadHandle == 0) | if (threadHandle == 0) | ||||
threadHandle = GetCurrentThread(); | threadHandle = GetCurrentThread(); | ||||
@@ -254012,6 +254024,105 @@ void InterProcessLock::exit() | |||||
if (pimpl != 0 && --(pimpl->refCount) == 0) | if (pimpl != 0 && --(pimpl->refCount) == 0) | ||||
pimpl = 0; | pimpl = 0; | ||||
} | } | ||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* userData) | |||||
{ | |||||
JUCE_AUTORELEASEPOOL | |||||
juce_threadEntryPoint (userData); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
struct sched_param param; | |||||
int policy; | |||||
priority = jlimit (0, 10, priority); | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0) | |||||
return false; | |||||
policy = priority == 0 ? SCHED_OTHER : SCHED_RR; | |||||
const int minPriority = sched_get_priority_min (policy); | |||||
const int maxPriority = sched_get_priority_max (policy); | |||||
param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority; | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return (ThreadID) pthread_self(); | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
/* Remove this macro if you're having problems compiling the cpu affinity | |||||
calls (the API for these has changed about quite a bit in various Linux | |||||
versions, and a lot of distros seem to ship with obsolete versions) | |||||
*/ | |||||
#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES) | |||||
#define SUPPORT_AFFINITIES 1 | |||||
#endif | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) | |||||
{ | |||||
#if SUPPORT_AFFINITIES | |||||
cpu_set_t affinity; | |||||
CPU_ZERO (&affinity); | |||||
for (int i = 0; i < 32; ++i) | |||||
if ((affinityMask & (1 << i)) != 0) | |||||
CPU_SET (i, &affinity); | |||||
/* | |||||
N.B. If this line causes a compile error, then you've probably not got the latest | |||||
version of glibc installed. | |||||
If you don't want to update your copy of glibc and don't care about cpu affinities, | |||||
then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0. | |||||
*/ | |||||
sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); | |||||
sched_yield(); | |||||
#else | |||||
/* affinities aren't supported because either the appropriate header files weren't found, | |||||
or the SUPPORT_AFFINITIES macro was turned off | |||||
*/ | |||||
jassertfalse; | |||||
#endif | |||||
} | |||||
/*** End of inlined file: juce_posix_SharedCode.h ***/ | /*** End of inlined file: juce_posix_SharedCode.h ***/ | ||||
@@ -255154,116 +255265,6 @@ bool Time::setSystemTimeToThisTime() const | |||||
live in juce_posix_SharedCode.h! | live in juce_posix_SharedCode.h! | ||||
*/ | */ | ||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* value) | |||||
{ | |||||
juce_threadEntryPoint (value); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return (ThreadID) pthread_self(); | |||||
} | |||||
/* This is all a bit non-ideal... the trouble is that on Linux you | |||||
need to call setpriority to affect the dynamic priority for | |||||
non-realtime processes, but this requires the pid, which is not | |||||
accessible from the pthread_t. We could get it by calling getpid | |||||
once each thread has started, but then we would need a list of | |||||
running threads etc etc. | |||||
Also there is no such thing as IDLE priority on Linux. | |||||
For the moment, map idle, low and normal process priorities to | |||||
SCHED_OTHER, with the thread priority ignored for these classes. | |||||
Map high priority processes to the lower half of the SCHED_RR | |||||
range, and realtime to the upper half. | |||||
priority 1 to 10 where 5=normal, 1=low. If the handle is 0, sets the | |||||
priority of the current thread | |||||
*/ | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
struct sched_param param; | |||||
int policy; | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) == 0 | |||||
&& policy != SCHED_OTHER) | |||||
{ | |||||
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
return false; | |||||
} | |||||
/* Remove this macro if you're having problems compiling the cpu affinity | |||||
calls (the API for these has changed about quite a bit in various Linux | |||||
versions, and a lot of distros seem to ship with obsolete versions) | |||||
*/ | |||||
#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES) | |||||
#define SUPPORT_AFFINITIES 1 | |||||
#endif | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) | |||||
{ | |||||
#if SUPPORT_AFFINITIES | |||||
cpu_set_t affinity; | |||||
CPU_ZERO (&affinity); | |||||
for (int i = 0; i < 32; ++i) | |||||
if ((affinityMask & (1 << i)) != 0) | |||||
CPU_SET (i, &affinity); | |||||
/* | |||||
N.B. If this line causes a compile error, then you've probably not got the latest | |||||
version of glibc installed. | |||||
If you don't want to update your copy of glibc and don't care about cpu affinities, | |||||
then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0. | |||||
*/ | |||||
sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); | |||||
sched_yield(); | |||||
#else | |||||
/* affinities aren't supported because either the appropriate header files weren't found, | |||||
or the SUPPORT_AFFINITIES macro was turned off | |||||
*/ | |||||
jassertfalse; | |||||
#endif | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
// sets the process to 0=low priority, 1=normal, 2=high, 3=realtime | // sets the process to 0=low priority, 1=normal, 2=high, 3=realtime | ||||
void Process::setPriority (ProcessPriority prior) | void Process::setPriority (ProcessPriority prior) | ||||
{ | { | ||||
@@ -263193,66 +263194,6 @@ int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOut | |||||
live in juce_posix_SharedCode.h! | live in juce_posix_SharedCode.h! | ||||
*/ | */ | ||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* userData) | |||||
{ | |||||
const ScopedAutoReleasePool pool; | |||||
juce_threadEntryPoint (userData); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
struct sched_param param; | |||||
int policy; | |||||
pthread_getschedparam ((pthread_t) handle, &policy, ¶m); | |||||
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return static_cast <ThreadID> (pthread_self()); | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 /*affinityMask*/) | |||||
{ | |||||
// xxx | |||||
jassertfalse; | |||||
} | |||||
bool Process::isForegroundProcess() | bool Process::isForegroundProcess() | ||||
{ | { | ||||
#if JUCE_MAC | #if JUCE_MAC | ||||
@@ -263865,6 +263806,105 @@ void InterProcessLock::exit() | |||||
if (pimpl != 0 && --(pimpl->refCount) == 0) | if (pimpl != 0 && --(pimpl->refCount) == 0) | ||||
pimpl = 0; | pimpl = 0; | ||||
} | } | ||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* userData) | |||||
{ | |||||
JUCE_AUTORELEASEPOOL | |||||
juce_threadEntryPoint (userData); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
struct sched_param param; | |||||
int policy; | |||||
priority = jlimit (0, 10, priority); | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0) | |||||
return false; | |||||
policy = priority == 0 ? SCHED_OTHER : SCHED_RR; | |||||
const int minPriority = sched_get_priority_min (policy); | |||||
const int maxPriority = sched_get_priority_max (policy); | |||||
param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority; | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return (ThreadID) pthread_self(); | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
/* Remove this macro if you're having problems compiling the cpu affinity | |||||
calls (the API for these has changed about quite a bit in various Linux | |||||
versions, and a lot of distros seem to ship with obsolete versions) | |||||
*/ | |||||
#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES) | |||||
#define SUPPORT_AFFINITIES 1 | |||||
#endif | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) | |||||
{ | |||||
#if SUPPORT_AFFINITIES | |||||
cpu_set_t affinity; | |||||
CPU_ZERO (&affinity); | |||||
for (int i = 0; i < 32; ++i) | |||||
if ((affinityMask & (1 << i)) != 0) | |||||
CPU_SET (i, &affinity); | |||||
/* | |||||
N.B. If this line causes a compile error, then you've probably not got the latest | |||||
version of glibc installed. | |||||
If you don't want to update your copy of glibc and don't care about cpu affinities, | |||||
then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0. | |||||
*/ | |||||
sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); | |||||
sched_yield(); | |||||
#else | |||||
/* affinities aren't supported because either the appropriate header files weren't found, | |||||
or the SUPPORT_AFFINITIES macro was turned off | |||||
*/ | |||||
jassertfalse; | |||||
#endif | |||||
} | |||||
/*** End of inlined file: juce_posix_SharedCode.h ***/ | /*** End of inlined file: juce_posix_SharedCode.h ***/ | ||||
@@ -265579,8 +265619,11 @@ public: | |||||
void fillRect (const Rectangle<int>& r, const bool replaceExistingContents) | void fillRect (const Rectangle<int>& r, const bool replaceExistingContents) | ||||
{ | { | ||||
CGRect cgRect = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); | |||||
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents); | |||||
} | |||||
void fillCGRect (const CGRect& cgRect, const bool replaceExistingContents) | |||||
{ | |||||
if (replaceExistingContents) | if (replaceExistingContents) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | ||||
@@ -265594,7 +265637,7 @@ public: | |||||
CGContextSetBlendMode (context, kCGBlendModeCopy); | CGContextSetBlendMode (context, kCGBlendModeCopy); | ||||
#endif | #endif | ||||
fillRect (r, false); | |||||
fillCGRect (cgRect, false); | |||||
CGContextSetBlendMode (context, kCGBlendModeNormal); | CGContextSetBlendMode (context, kCGBlendModeNormal); | ||||
} | } | ||||
else | else | ||||
@@ -265710,38 +265753,61 @@ public: | |||||
void drawLine (const Line<float>& line) | void drawLine (const Line<float>& line) | ||||
{ | { | ||||
CGContextSetLineCap (context, kCGLineCapSquare); | |||||
CGContextSetLineWidth (context, 1.0f); | |||||
CGContextSetRGBStrokeColor (context, | |||||
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), | |||||
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
CGContextSetLineCap (context, kCGLineCapSquare); | |||||
CGContextSetLineWidth (context, 1.0f); | |||||
CGContextSetRGBStrokeColor (context, | |||||
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), | |||||
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); | |||||
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, | |||||
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; | |||||
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, | |||||
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; | |||||
CGContextStrokeLineSegments (context, cgLine, 1); | |||||
CGContextStrokeLineSegments (context, cgLine, 1); | |||||
} | |||||
else | |||||
{ | |||||
Path p; | |||||
p.addLineSegment (line, 1.0f); | |||||
fillPath (p, AffineTransform::identity); | |||||
} | |||||
} | } | ||||
void drawVerticalLine (const int x, float top, float bottom) | void drawVerticalLine (const int x, float top, float bottom) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||||
#endif | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
fillCGRect (CGRectMake ((float) x, flipHeight - bottom, 1.0f, bottom - top), false); | |||||
} | |||||
} | } | ||||
void drawHorizontalLine (const int y, float left, float right) | void drawHorizontalLine (const int y, float left, float right) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||||
#endif | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
fillCGRect (CGRectMake (left, flipHeight - (y + 1), right - left, 1.0f), false); | |||||
} | |||||
} | } | ||||
void setFont (const Font& newFont) | void setFont (const Font& newFont) | ||||
@@ -270180,8 +270246,11 @@ public: | |||||
void fillRect (const Rectangle<int>& r, const bool replaceExistingContents) | void fillRect (const Rectangle<int>& r, const bool replaceExistingContents) | ||||
{ | { | ||||
CGRect cgRect = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); | |||||
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents); | |||||
} | |||||
void fillCGRect (const CGRect& cgRect, const bool replaceExistingContents) | |||||
{ | |||||
if (replaceExistingContents) | if (replaceExistingContents) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | ||||
@@ -270195,7 +270264,7 @@ public: | |||||
CGContextSetBlendMode (context, kCGBlendModeCopy); | CGContextSetBlendMode (context, kCGBlendModeCopy); | ||||
#endif | #endif | ||||
fillRect (r, false); | |||||
fillCGRect (cgRect, false); | |||||
CGContextSetBlendMode (context, kCGBlendModeNormal); | CGContextSetBlendMode (context, kCGBlendModeNormal); | ||||
} | } | ||||
else | else | ||||
@@ -270311,38 +270380,61 @@ public: | |||||
void drawLine (const Line<float>& line) | void drawLine (const Line<float>& line) | ||||
{ | { | ||||
CGContextSetLineCap (context, kCGLineCapSquare); | |||||
CGContextSetLineWidth (context, 1.0f); | |||||
CGContextSetRGBStrokeColor (context, | |||||
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), | |||||
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
CGContextSetLineCap (context, kCGLineCapSquare); | |||||
CGContextSetLineWidth (context, 1.0f); | |||||
CGContextSetRGBStrokeColor (context, | |||||
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), | |||||
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); | |||||
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, | |||||
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; | |||||
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, | |||||
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; | |||||
CGContextStrokeLineSegments (context, cgLine, 1); | |||||
CGContextStrokeLineSegments (context, cgLine, 1); | |||||
} | |||||
else | |||||
{ | |||||
Path p; | |||||
p.addLineSegment (line, 1.0f); | |||||
fillPath (p, AffineTransform::identity); | |||||
} | |||||
} | } | ||||
void drawVerticalLine (const int x, float top, float bottom) | void drawVerticalLine (const int x, float top, float bottom) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||||
#endif | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
fillCGRect (CGRectMake ((float) x, flipHeight - bottom, 1.0f, bottom - top), false); | |||||
} | |||||
} | } | ||||
void drawHorizontalLine (const int y, float left, float right) | void drawHorizontalLine (const int y, float left, float right) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||||
#endif | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
fillCGRect (CGRectMake (left, flipHeight - (y + 1), right - left, 1.0f), false); | |||||
} | |||||
} | } | ||||
void setFont (const Font& newFont) | void setFont (const Font& newFont) | ||||
@@ -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 50 | |||||
#define JUCE_BUILDNUMBER 51 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -6712,8 +6712,9 @@ private: | |||||
virtual const String toString() const = 0; | virtual const String toString() const = 0; | ||||
virtual int getOperatorPrecedence() const; | virtual int getOperatorPrecedence() const; | ||||
virtual bool referencesSymbol (const String& symbol, const EvaluationContext&, int recursionDepth) const; | virtual bool referencesSymbol (const String& symbol, const EvaluationContext&, int recursionDepth) const; | ||||
virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, 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(); | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
@@ -43125,9 +43126,6 @@ public: | |||||
private: | private: | ||||
Expression term; | Expression term; | ||||
// double resolve (const Expression::EvaluationContext* evaluationContext, int recursionCounter) const; | |||||
// static double resolveAnchor (const String& anchorName, const Expression::EvaluationContext* evaluationContext, int recursionCounter); | |||||
}; | }; | ||||
/** | /** | ||||
@@ -35,6 +35,8 @@ BEGIN_JUCE_NAMESPACE | |||||
class Expression::Helpers | class Expression::Helpers | ||||
{ | { | ||||
public: | public: | ||||
typedef ReferenceCountedObjectPtr<Term> TermPtr; | |||||
//============================================================================== | //============================================================================== | ||||
class Constant : public Term | class Constant : public Term | ||||
{ | { | ||||
@@ -46,6 +48,11 @@ public: | |||||
int getNumInputs() const { return 0; } | int getNumInputs() const { return 0; } | ||||
Term* getInput (int) const { return 0; } | Term* getInput (int) const { return 0; } | ||||
const TermPtr negated() | |||||
{ | |||||
return new Constant (-value); | |||||
} | |||||
const String toString() const | const String toString() const | ||||
{ | { | ||||
if (isResolutionTarget) | if (isResolutionTarget) | ||||
@@ -69,7 +76,14 @@ public: | |||||
if (++recursionDepth > 256) | if (++recursionDepth > 256) | ||||
throw EvaluationError ("Recursive symbol references"); | throw EvaluationError ("Recursive symbol references"); | ||||
return c.getSymbolValue (symbol).term->evaluate (c, recursionDepth); | |||||
try | |||||
{ | |||||
return c.getSymbolValue (symbol).term->evaluate (c, recursionDepth); | |||||
} | |||||
catch (...) | |||||
{} | |||||
return 0; | |||||
} | } | ||||
Term* clone() const { return new Symbol (symbol); } | Term* clone() const { return new Symbol (symbol); } | ||||
@@ -150,7 +164,7 @@ public: | |||||
class Negate : public Term | class Negate : public Term | ||||
{ | { | ||||
public: | public: | ||||
Negate (Term* const input_) : input (input_) | |||||
Negate (const TermPtr& input_) : input (input_) | |||||
{ | { | ||||
jassert (input_ != 0); | jassert (input_ != 0); | ||||
} | } | ||||
@@ -161,18 +175,19 @@ public: | |||||
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 ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, Term* input_, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr negated() | |||||
{ | |||||
return input; | |||||
} | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& context, const Term* input_, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
jassert (input_ == input); | jassert (input_ == input); | ||||
const Term* const dest = findDestinationFor (topLevelTerm, this); | const Term* const dest = findDestinationFor (topLevelTerm, this); | ||||
Term* newDest; | |||||
if (dest == 0) | |||||
newDest = new Constant (overallTarget); | |||||
else | |||||
newDest = dest->clone(); | |||||
return new Negate (newDest); | |||||
return new Negate (dest == 0 ? new Constant (overallTarget) | |||||
: dest->createTermToEvaluateInput (context, this, overallTarget, topLevelTerm)); | |||||
} | } | ||||
const String toString() const | const String toString() const | ||||
@@ -189,7 +204,7 @@ public: | |||||
} | } | ||||
private: | private: | ||||
const ReferenceCountedObjectPtr<Term> input; | |||||
const TermPtr input; | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
@@ -216,7 +231,7 @@ public: | |||||
} | } | ||||
protected: | protected: | ||||
const ReferenceCountedObjectPtr<Term> left, right; | |||||
const TermPtr left, right; | |||||
const String createString (const String& op) const | const String createString (const String& op) const | ||||
{ | { | ||||
@@ -238,7 +253,7 @@ public: | |||||
return s; | return s; | ||||
} | } | ||||
Term* createDestinationTerm (const EvaluationContext&, 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); | ||||
if (input != left && input != right) | if (input != left && input != right) | ||||
@@ -249,7 +264,7 @@ public: | |||||
if (dest == 0) | if (dest == 0) | ||||
return new Constant (overallTarget); | return new Constant (overallTarget); | ||||
return dest->clone(); | |||||
return dest->createTermToEvaluateInput (context, this, overallTarget, topLevelTerm); | |||||
} | } | ||||
}; | }; | ||||
@@ -264,9 +279,9 @@ public: | |||||
const String toString() const { return createString ("+"); } | const String toString() const { return createString ("+"); } | ||||
int getOperatorPrecedence() const { return 2; } | int getOperatorPrecedence() const { return 2; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -285,9 +300,9 @@ public: | |||||
const String toString() const { return createString ("-"); } | const String toString() const { return createString ("-"); } | ||||
int getOperatorPrecedence() const { return 2; } | int getOperatorPrecedence() const { return 2; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -309,9 +324,9 @@ public: | |||||
const String toString() const { return createString ("*"); } | const String toString() const { return createString ("*"); } | ||||
int getOperatorPrecedence() const { return 1; } | int getOperatorPrecedence() const { return 1; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -330,9 +345,9 @@ public: | |||||
const String toString() const { return createString ("/"); } | const String toString() const { return createString ("/"); } | ||||
int getOperatorPrecedence() const { return 1; } | int getOperatorPrecedence() const { return 1; } | ||||
const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext& c, Term* input, double overallTarget, Term* topLevelTerm) const | |||||
const TermPtr createTermToEvaluateInput (const EvaluationContext& c, const Term* input, double overallTarget, Term* topLevelTerm) const | |||||
{ | { | ||||
Term* const newDest = createDestinationTerm (c, input, overallTarget, topLevelTerm); | |||||
const TermPtr newDest (createDestinationTerm (c, input, overallTarget, topLevelTerm)); | |||||
if (newDest == 0) | if (newDest == 0) | ||||
return 0; | return 0; | ||||
@@ -435,25 +450,25 @@ public: | |||||
text = textString; | text = textString; | ||||
} | } | ||||
Term* readExpression() | |||||
const TermPtr readExpression() | |||||
{ | { | ||||
ScopedPointer<Term> lhs (readMultiplyOrDivideExpression()); | |||||
TermPtr lhs (readMultiplyOrDivideExpression()); | |||||
char opType; | char opType; | ||||
while (lhs != 0 && readOperator ("+-", &opType)) | while (lhs != 0 && readOperator ("+-", &opType)) | ||||
{ | { | ||||
Term* rhs = readMultiplyOrDivideExpression(); | |||||
TermPtr rhs (readMultiplyOrDivideExpression()); | |||||
if (rhs == 0) | if (rhs == 0) | ||||
throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | ||||
if (opType == '+') | if (opType == '+') | ||||
lhs = new Add (lhs.release(), rhs); | |||||
lhs = new Add (lhs, rhs); | |||||
else | else | ||||
lhs = new Subtract (lhs.release(), rhs); | |||||
lhs = new Subtract (lhs, rhs); | |||||
} | } | ||||
return lhs.release(); | |||||
return lhs; | |||||
} | } | ||||
private: | private: | ||||
@@ -590,39 +605,39 @@ public: | |||||
return t; | return t; | ||||
} | } | ||||
Term* readMultiplyOrDivideExpression() | |||||
const TermPtr readMultiplyOrDivideExpression() | |||||
{ | { | ||||
ScopedPointer<Term> lhs (readUnaryExpression()); | |||||
TermPtr lhs (readUnaryExpression()); | |||||
char opType; | char opType; | ||||
while (lhs != 0 && readOperator ("*/", &opType)) | while (lhs != 0 && readOperator ("*/", &opType)) | ||||
{ | { | ||||
Term* rhs = readUnaryExpression(); | |||||
TermPtr rhs (readUnaryExpression()); | |||||
if (rhs == 0) | if (rhs == 0) | ||||
throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | ||||
if (opType == '*') | if (opType == '*') | ||||
lhs = new Multiply (lhs.release(), rhs); | |||||
lhs = new Multiply (lhs, rhs); | |||||
else | else | ||||
lhs = new Divide (lhs.release(), rhs); | |||||
lhs = new Divide (lhs, rhs); | |||||
} | } | ||||
return lhs.release(); | |||||
return lhs; | |||||
} | } | ||||
Term* readUnaryExpression() | |||||
const TermPtr readUnaryExpression() | |||||
{ | { | ||||
char opType; | char opType; | ||||
if (readOperator ("+-", &opType)) | if (readOperator ("+-", &opType)) | ||||
{ | { | ||||
Term* term = readUnaryExpression(); | |||||
TermPtr term (readUnaryExpression()); | |||||
if (term == 0) | if (term == 0) | ||||
throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | throw ParseError ("Expected expression after \"" + String::charToString (opType) + "\""); | ||||
if (opType == '-') | if (opType == '-') | ||||
term = new Negate (term); | |||||
term = term->negated(); | |||||
return term; | return term; | ||||
} | } | ||||
@@ -630,9 +645,9 @@ public: | |||||
return readPrimaryExpression(); | return readPrimaryExpression(); | ||||
} | } | ||||
Term* readPrimaryExpression() | |||||
const TermPtr readPrimaryExpression() | |||||
{ | { | ||||
Term* e = readParenthesisedExpression(); | |||||
TermPtr e (readParenthesisedExpression()); | |||||
if (e != 0) | if (e != 0) | ||||
return e; | return e; | ||||
@@ -648,7 +663,7 @@ public: | |||||
Function* f = new Function (identifier, ReferenceCountedArray<Term>()); | Function* f = new Function (identifier, ReferenceCountedArray<Term>()); | ||||
ScopedPointer<Term> func (f); // (can't use ScopedPointer<Function> in MSVC) | ScopedPointer<Term> func (f); // (can't use ScopedPointer<Function> in MSVC) | ||||
Term* param = readExpression(); | |||||
TermPtr param (readExpression()); | |||||
if (param == 0) | if (param == 0) | ||||
{ | { | ||||
@@ -684,19 +699,16 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
Term* readParenthesisedExpression() | |||||
const TermPtr readParenthesisedExpression() | |||||
{ | { | ||||
if (! readOperator ("(")) | if (! readOperator ("(")) | ||||
return 0; | return 0; | ||||
ScopedPointer<Term> e (readExpression()); | |||||
if (e == 0) | |||||
const TermPtr e (readExpression()); | |||||
if (e == 0 || ! readOperator (")")) | |||||
return 0; | return 0; | ||||
if (! readOperator (")")) | |||||
e = 0; | |||||
return e.release(); | |||||
return e; | |||||
} | } | ||||
Parser (const Parser&); | Parser (const Parser&); | ||||
@@ -749,7 +761,7 @@ Expression::Expression (const String& stringToParse) | |||||
const Expression Expression::parse (const String& stringToParse, int& textIndexToStartFrom) | const Expression Expression::parse (const String& stringToParse, int& textIndexToStartFrom) | ||||
{ | { | ||||
Helpers::Parser parser (stringToParse, textIndexToStartFrom); | Helpers::Parser parser (stringToParse, textIndexToStartFrom); | ||||
Term* term = parser.readExpression(); | |||||
const Helpers::TermPtr term (parser.readExpression()); | |||||
if (term != 0) | if (term != 0) | ||||
return Expression (term); | return Expression (term); | ||||
@@ -789,7 +801,7 @@ const Expression Expression::operator/ (const Expression& other) const | |||||
const Expression Expression::operator-() const | const Expression Expression::operator-() const | ||||
{ | { | ||||
return Expression (new Helpers::Negate (term)); | |||||
return Expression (term->negated()); | |||||
} | } | ||||
const String Expression::toString() const | const String Expression::toString() const | ||||
@@ -837,7 +849,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
const ReferenceCountedObjectPtr<Term> reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | |||||
const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (context, termToAdjust, targetValue, newTerm)); | |||||
if (reverseTerm == 0) | if (reverseTerm == 0) | ||||
return Expression(); | return Expression(); | ||||
@@ -883,21 +895,28 @@ int Expression::Term::getInputIndexFor (const Term*) const | |||||
return -1; | return -1; | ||||
} | } | ||||
const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::createTermToEvaluateInput (const EvaluationContext&, Term*, double, Term*) const | |||||
const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::createTermToEvaluateInput (const EvaluationContext&, const Term*, double, Term*) const | |||||
{ | { | ||||
jassertfalse; | jassertfalse; | ||||
return 0; | return 0; | ||||
} | } | ||||
const ReferenceCountedObjectPtr<Expression::Term> Expression::Term::negated() | |||||
{ | |||||
return new Helpers::Negate (this); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
Expression::ParseError::ParseError (const String& message) | Expression::ParseError::ParseError (const String& message) | ||||
: description (message) | : description (message) | ||||
{ | { | ||||
DBG ("Expression::ParseError: " + message); | |||||
} | } | ||||
Expression::EvaluationError::EvaluationError (const String& message) | Expression::EvaluationError::EvaluationError (const String& message) | ||||
: description (message) | : description (message) | ||||
{ | { | ||||
DBG ("Expression::EvaluationError: " + message); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -198,8 +198,9 @@ private: | |||||
virtual const String toString() const = 0; | virtual const String toString() const = 0; | ||||
virtual int getOperatorPrecedence() const; | virtual int getOperatorPrecedence() const; | ||||
virtual bool referencesSymbol (const String& symbol, const EvaluationContext&, int recursionDepth) const; | virtual bool referencesSymbol (const String& symbol, const EvaluationContext&, int recursionDepth) const; | ||||
virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, 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(); | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
@@ -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 50 | |||||
#define JUCE_BUILDNUMBER 51 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -185,7 +185,7 @@ const String RelativeCoordinate::toString() const | |||||
void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName, | ||||
const Expression::EvaluationContext* context) | const Expression::EvaluationContext* context) | ||||
{ | { | ||||
jassert (newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); | |||||
if (term.referencesSymbol (oldName, *context)) | if (term.referencesSymbol (oldName, *context)) | ||||
{ | { | ||||
@@ -276,9 +276,9 @@ RelativeRectangle::RelativeRectangle (const RelativeCoordinate& left_, const Rel | |||||
RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect, const String& componentName) | RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect, const String& componentName) | ||||
: left (rect.getX()), | : left (rect.getX()), | ||||
right (componentName + "." + RelativeCoordinate::Strings::left + " + " + String (rect.getWidth())), | |||||
right (Expression::symbol (componentName + "." + RelativeCoordinate::Strings::left) + Expression ((double) rect.getWidth())), | |||||
top (rect.getY()), | top (rect.getY()), | ||||
bottom (componentName + "." + RelativeCoordinate::Strings::top + " + " + String (rect.getHeight())) | |||||
bottom (Expression::symbol (componentName + "." + RelativeCoordinate::Strings::top) + Expression ((double) rect.getHeight())) | |||||
{ | { | ||||
} | } | ||||
@@ -144,9 +144,6 @@ public: | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
Expression term; | Expression term; | ||||
// double resolve (const Expression::EvaluationContext* evaluationContext, int recursionCounter) const; | |||||
// static double resolveAnchor (const String& anchorName, const Expression::EvaluationContext* evaluationContext, int recursionCounter); | |||||
}; | }; | ||||
@@ -615,3 +615,104 @@ void InterProcessLock::exit() | |||||
if (pimpl != 0 && --(pimpl->refCount) == 0) | if (pimpl != 0 && --(pimpl->refCount) == 0) | ||||
pimpl = 0; | pimpl = 0; | ||||
} | } | ||||
//============================================================================== | |||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* userData) | |||||
{ | |||||
JUCE_AUTORELEASEPOOL | |||||
juce_threadEntryPoint (userData); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
struct sched_param param; | |||||
int policy; | |||||
priority = jlimit (0, 10, priority); | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) != 0) | |||||
return false; | |||||
policy = priority == 0 ? SCHED_OTHER : SCHED_RR; | |||||
const int minPriority = sched_get_priority_min (policy); | |||||
const int maxPriority = sched_get_priority_max (policy); | |||||
param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority; | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return (ThreadID) pthread_self(); | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
//============================================================================== | |||||
/* Remove this macro if you're having problems compiling the cpu affinity | |||||
calls (the API for these has changed about quite a bit in various Linux | |||||
versions, and a lot of distros seem to ship with obsolete versions) | |||||
*/ | |||||
#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES) | |||||
#define SUPPORT_AFFINITIES 1 | |||||
#endif | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) | |||||
{ | |||||
#if SUPPORT_AFFINITIES | |||||
cpu_set_t affinity; | |||||
CPU_ZERO (&affinity); | |||||
for (int i = 0; i < 32; ++i) | |||||
if ((affinityMask & (1 << i)) != 0) | |||||
CPU_SET (i, &affinity); | |||||
/* | |||||
N.B. If this line causes a compile error, then you've probably not got the latest | |||||
version of glibc installed. | |||||
If you don't want to update your copy of glibc and don't care about cpu affinities, | |||||
then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0. | |||||
*/ | |||||
sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); | |||||
sched_yield(); | |||||
#else | |||||
/* affinities aren't supported because either the appropriate header files weren't found, | |||||
or the SUPPORT_AFFINITIES macro was turned off | |||||
*/ | |||||
jassertfalse; | |||||
#endif | |||||
} |
@@ -32,118 +32,6 @@ | |||||
live in juce_posix_SharedCode.h! | live in juce_posix_SharedCode.h! | ||||
*/ | */ | ||||
//============================================================================== | |||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* value) | |||||
{ | |||||
juce_threadEntryPoint (value); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return (ThreadID) pthread_self(); | |||||
} | |||||
/* This is all a bit non-ideal... the trouble is that on Linux you | |||||
need to call setpriority to affect the dynamic priority for | |||||
non-realtime processes, but this requires the pid, which is not | |||||
accessible from the pthread_t. We could get it by calling getpid | |||||
once each thread has started, but then we would need a list of | |||||
running threads etc etc. | |||||
Also there is no such thing as IDLE priority on Linux. | |||||
For the moment, map idle, low and normal process priorities to | |||||
SCHED_OTHER, with the thread priority ignored for these classes. | |||||
Map high priority processes to the lower half of the SCHED_RR | |||||
range, and realtime to the upper half. | |||||
priority 1 to 10 where 5=normal, 1=low. If the handle is 0, sets the | |||||
priority of the current thread | |||||
*/ | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
struct sched_param param; | |||||
int policy; | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
if (pthread_getschedparam ((pthread_t) handle, &policy, ¶m) == 0 | |||||
&& policy != SCHED_OTHER) | |||||
{ | |||||
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
return false; | |||||
} | |||||
/* Remove this macro if you're having problems compiling the cpu affinity | |||||
calls (the API for these has changed about quite a bit in various Linux | |||||
versions, and a lot of distros seem to ship with obsolete versions) | |||||
*/ | |||||
#if defined (CPU_ISSET) && ! defined (SUPPORT_AFFINITIES) | |||||
#define SUPPORT_AFFINITIES 1 | |||||
#endif | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) | |||||
{ | |||||
#if SUPPORT_AFFINITIES | |||||
cpu_set_t affinity; | |||||
CPU_ZERO (&affinity); | |||||
for (int i = 0; i < 32; ++i) | |||||
if ((affinityMask & (1 << i)) != 0) | |||||
CPU_SET (i, &affinity); | |||||
/* | |||||
N.B. If this line causes a compile error, then you've probably not got the latest | |||||
version of glibc installed. | |||||
If you don't want to update your copy of glibc and don't care about cpu affinities, | |||||
then you can just disable all this stuff by setting the SUPPORT_AFFINITIES macro to 0. | |||||
*/ | |||||
sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); | |||||
sched_yield(); | |||||
#else | |||||
/* affinities aren't supported because either the appropriate header files weren't found, | |||||
or the SUPPORT_AFFINITIES macro was turned off | |||||
*/ | |||||
jassertfalse; | |||||
#endif | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
// sets the process to 0=low priority, 1=normal, 2=high, 3=realtime | // sets the process to 0=low priority, 1=normal, 2=high, 3=realtime | ||||
void Process::setPriority (ProcessPriority prior) | void Process::setPriority (ProcessPriority prior) | ||||
@@ -340,8 +340,11 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
void fillRect (const Rectangle<int>& r, const bool replaceExistingContents) | void fillRect (const Rectangle<int>& r, const bool replaceExistingContents) | ||||
{ | { | ||||
CGRect cgRect = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); | |||||
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents); | |||||
} | |||||
void fillCGRect (const CGRect& cgRect, const bool replaceExistingContents) | |||||
{ | |||||
if (replaceExistingContents) | if (replaceExistingContents) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 | ||||
@@ -355,7 +358,7 @@ public: | |||||
CGContextSetBlendMode (context, kCGBlendModeCopy); | CGContextSetBlendMode (context, kCGBlendModeCopy); | ||||
#endif | #endif | ||||
fillRect (r, false); | |||||
fillCGRect (cgRect, false); | |||||
CGContextSetBlendMode (context, kCGBlendModeNormal); | CGContextSetBlendMode (context, kCGBlendModeNormal); | ||||
} | } | ||||
else | else | ||||
@@ -472,38 +475,61 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
void drawLine (const Line<float>& line) | void drawLine (const Line<float>& line) | ||||
{ | { | ||||
CGContextSetLineCap (context, kCGLineCapSquare); | |||||
CGContextSetLineWidth (context, 1.0f); | |||||
CGContextSetRGBStrokeColor (context, | |||||
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), | |||||
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
CGContextSetLineCap (context, kCGLineCapSquare); | |||||
CGContextSetLineWidth (context, 1.0f); | |||||
CGContextSetRGBStrokeColor (context, | |||||
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(), | |||||
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha()); | |||||
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, | |||||
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; | |||||
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() }, | |||||
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } }; | |||||
CGContextStrokeLineSegments (context, cgLine, 1); | |||||
CGContextStrokeLineSegments (context, cgLine, 1); | |||||
} | |||||
else | |||||
{ | |||||
Path p; | |||||
p.addLineSegment (line, 1.0f); | |||||
fillPath (p, AffineTransform::identity); | |||||
} | |||||
} | } | ||||
void drawVerticalLine (const int x, float top, float bottom) | void drawVerticalLine (const int x, float top, float bottom) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||||
#endif | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (x, flipHeight - bottom, 1.0f, bottom - top)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (x + 1.0f / 256.0f, flipHeight - bottom, 1.0f + 1.0f / 256.0f, bottom - top)); | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
fillCGRect (CGRectMake ((float) x, flipHeight - bottom, 1.0f, bottom - top), false); | |||||
} | |||||
} | } | ||||
void drawHorizontalLine (const int y, float left, float right) | void drawHorizontalLine (const int y, float left, float right) | ||||
{ | { | ||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||||
#endif | |||||
if (state->fillType.isColour()) | |||||
{ | |||||
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + 1.0f), right - left, 1.0f)); | |||||
#else | |||||
// On Leopard, unless both co-ordinates are non-integer, it disables anti-aliasing, so nudge | |||||
// the x co-ord slightly to trick it.. | |||||
CGContextFillRect (context, CGRectMake (left, flipHeight - (y + (1.0f + 1.0f / 256.0f)), right - left, 1.0f + 1.0f / 256.0f)); | |||||
#endif | |||||
} | |||||
else | |||||
{ | |||||
fillCGRect (CGRectMake (left, flipHeight - (y + 1), right - left, 1.0f), false); | |||||
} | |||||
} | } | ||||
void setFont (const Font& newFont) | void setFont (const Font& newFont) | ||||
@@ -33,67 +33,6 @@ | |||||
live in juce_posix_SharedCode.h! | live in juce_posix_SharedCode.h! | ||||
*/ | */ | ||||
//============================================================================== | |||||
void JUCE_API juce_threadEntryPoint (void*); | |||||
void* threadEntryProc (void* userData) | |||||
{ | |||||
const ScopedAutoReleasePool pool; | |||||
juce_threadEntryPoint (userData); | |||||
return 0; | |||||
} | |||||
void* juce_createThread (void* userData) | |||||
{ | |||||
pthread_t handle = 0; | |||||
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||||
{ | |||||
pthread_detach (handle); | |||||
return (void*) handle; | |||||
} | |||||
return 0; | |||||
} | |||||
void juce_killThread (void* handle) | |||||
{ | |||||
if (handle != 0) | |||||
pthread_cancel ((pthread_t) handle); | |||||
} | |||||
void juce_setCurrentThreadName (const String& /*name*/) | |||||
{ | |||||
} | |||||
bool juce_setThreadPriority (void* handle, int priority) | |||||
{ | |||||
if (handle == 0) | |||||
handle = (void*) pthread_self(); | |||||
struct sched_param param; | |||||
int policy; | |||||
pthread_getschedparam ((pthread_t) handle, &policy, ¶m); | |||||
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); | |||||
return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; | |||||
} | |||||
Thread::ThreadID Thread::getCurrentThreadId() | |||||
{ | |||||
return static_cast <ThreadID> (pthread_self()); | |||||
} | |||||
void Thread::yield() | |||||
{ | |||||
sched_yield(); | |||||
} | |||||
void Thread::setCurrentThreadAffinityMask (const uint32 /*affinityMask*/) | |||||
{ | |||||
// xxx | |||||
jassertfalse; | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
bool Process::isForegroundProcess() | bool Process::isForegroundProcess() | ||||
{ | { | ||||
@@ -188,18 +188,12 @@ bool juce_setThreadPriority (void* threadHandle, int priority) | |||||
{ | { | ||||
int pri = THREAD_PRIORITY_TIME_CRITICAL; | int pri = THREAD_PRIORITY_TIME_CRITICAL; | ||||
if (priority < 1) | |||||
pri = THREAD_PRIORITY_IDLE; | |||||
else if (priority < 2) | |||||
pri = THREAD_PRIORITY_LOWEST; | |||||
else if (priority < 5) | |||||
pri = THREAD_PRIORITY_BELOW_NORMAL; | |||||
else if (priority < 7) | |||||
pri = THREAD_PRIORITY_NORMAL; | |||||
else if (priority < 9) | |||||
pri = THREAD_PRIORITY_ABOVE_NORMAL; | |||||
else if (priority < 10) | |||||
pri = THREAD_PRIORITY_HIGHEST; | |||||
if (priority < 1) pri = THREAD_PRIORITY_IDLE; | |||||
else if (priority < 2) pri = THREAD_PRIORITY_LOWEST; | |||||
else if (priority < 5) pri = THREAD_PRIORITY_BELOW_NORMAL; | |||||
else if (priority < 7) pri = THREAD_PRIORITY_NORMAL; | |||||
else if (priority < 9) pri = THREAD_PRIORITY_ABOVE_NORMAL; | |||||
else if (priority < 10) pri = THREAD_PRIORITY_HIGHEST; | |||||
if (threadHandle == 0) | if (threadHandle == 0) | ||||
threadHandle = GetCurrentThread(); | threadHandle = GetCurrentThread(); | ||||