RunnerThread( MarSystem * system, Runner::Shared * shared, bool realtime_priority, unsigned int ticks ): m_system(system), m_shared(shared), m_ticks(ticks > 0 ? ticks : -1), m_stop(false), m_thread(&Marsyas::RealTime::RunnerThread::run, this) { #if defined(MARSYAS_MACOSX) || defined(MARSYAS_LINUX) int policy; sched_param param; pthread_getschedparam( m_thread.native_handle(), &policy, ¶m ); policy = realtime_priority ? SCHED_RR : SCHED_OTHER; int min_priority = sched_get_priority_min( policy ); int max_priority = sched_get_priority_max( policy ); int relative_priority = (int) ((max_priority - min_priority) * 0.6); int priority = min_priority + relative_priority; param.sched_priority = priority; if (pthread_setschedparam( m_thread.native_handle(), policy, ¶m )) { MRSWARN("RunnerThread: Failed to set thread scheduling policy and priority: " << std::strerror(errno)); } #elif defined(MARSYAS_WIN32) || defined(MARSYAS_MINGW) if (!SetThreadPriority( m_thread.native_handle(), THREAD_PRIORITY_HIGHEST )) { MRSWARN("RunnerThread: Failed to set thread priority."); } #else MRSWARN("RunnerThread: Increasing thread priority on this platform is not implemented yet."); #endif }
WAS_INLINE bool MarControl::setValue(MarControlValue *mcv, bool update) { if (value_->type_ != mcv->type_) { std::ostringstream sstr; sstr << "MarControl::setValue() - Trying to set value of incompatible type " << "(expected " << value_->type_ << ", given " << mcv->type_ << ")"; MRSWARN(sstr.str()); return false; } if (!mcv->isNotEqual(value_)) { return true; } value_->copyValue(*(mcv)); #ifdef MARSYAS_TRACECONTROLS value_->setDebugValue(); #endif //check if it's needed to call update() if(update) value_->callMarSystemsUpdate(); return true; }
void process_message( MarSystem * root_system, const osc::ReceivedMessage& message ) { const char * path = message.AddressPattern(); if (path[0] == '/') ++path; // FIXME: Constructing std::string is not real-time-safe. MarControlPtr control = find_control(root_system, path); if (control.isInvalid()) { MRSWARN("OSC receiver: no control for path: " << path); return; } try { osc::ReceivedMessage::const_iterator it = message.ArgumentsBegin(); if (it == message.ArgumentsEnd()) throw std::runtime_error("OSC receiver: Message has no arguments."); char tag = it->TypeTag(); switch(tag) { case osc::TRUE_TYPE_TAG: case osc::FALSE_TYPE_TAG: control->setValue(it->AsBoolUnchecked()); break; case osc::INT32_TYPE_TAG: control->setValue(it->AsInt32Unchecked()); break; case osc::FLOAT_TYPE_TAG: control->setValue((mrs_real) it->AsFloatUnchecked()); break; case osc::DOUBLE_TYPE_TAG: control->setValue((mrs_real) it->AsDoubleUnchecked()); break; case osc::STRING_TYPE_TAG: control->setValue(it->AsStringUnchecked()); break; default: throw std::runtime_error("OSC receiver: Unsupported message argument type."); } } catch ( std::exception & e ) { MRSWARN("OSC receiver: error while parsing message: " << e.what()); } }
void OscQueueProvider::provide( OscProviderDestination & destination ) { size_t packet_size; while( (packet_size = m_queue->pop(m_buffer, m_buffer_size)) ) { if (packet_size > m_buffer_size) { MRSWARN("OSC receiver: dropped too large OSC packet."); continue; } destination.provide(m_buffer, packet_size); } }
WAS_INLINE bool MarControl::isTrue() { MarControlValueT<bool> *ptr = dynamic_cast<MarControlValueT<bool>*>(value_); if(ptr) { return ptr->get(); } else { std::ostringstream sstr; sstr << "MarControl::isTrue() - Trying to get use bool-specific method with " << value_->getType(); MRSWARN(sstr.str()); return false; } }
WAS_INLINE mrs_real operator-(const MarControl& v1, const mrs_real& v2) { mrs_real r1; MarControlValueT<mrs_real> *ptr = dynamic_cast<MarControlValueT<mrs_real>*>(v1.value_); if(ptr) { r1 = ptr->get(); } else { std::ostringstream sstr; sstr << "[MarControl::setValue] Trying to get value of incompatible type " << "(expected " << v1.getType() << ", given " << typeid(mrs_real).name() << ")"; MRSWARN(sstr.str()); return false; } return r1 - v2; }
bool MarControl::linkTo(MarControlPtr ctrl, bool update) { if (ctrl.isInvalid()) { ostringstream oss; oss << "MarControl::linkTo() - Linking to an invalid control "; oss << "(" << ctrl->cname_ << " with " << cname_ << ")."; MRSWARN(oss.str()); return false; } //check if these controls are already linked //(i.e. they own the same MarControlValue) if(value_ == ctrl->value_) { return true;//already linked! :-) } if (ctrl->value_->type_ != value_->type_) { ostringstream oss; oss << "MarControl::linkTo() - Linking controls of different types "; oss << "(" << ctrl->cname_ << " with " << cname_ << ")."; MRSWARN(oss.str()); return false; } //unlink this control (but keeping all links to it) //before linking it again to the passed control this->unlinkFromTarget(); //store a pointer to the (soon to be old) MarControlValue object, //so we can later delete it from memory MarControlValue* oldvalue = value_; //and get a pointer to the new value MarControlValue* newvalue = ctrl->value_; //get all the links of our current MarControlValue so we can also //re-link them to the passed ctrl vector<pair<MarControl*, MarControl*> >::iterator lit; for(lit=oldvalue->links_.begin(); lit!=oldvalue->links_.end(); ++lit) { //make each linked control now point to the "passed" MarControlValue lit->first->value_ = newvalue; // check if this is the root link if(lit->first == lit->second) { //make it "link to" the passed control newvalue->links_.push_back(pair<MarControl*, MarControl*>(lit->first, ctrl())); } else //if not a root link, just copy the table entry unchanged into the new MarControlValue newvalue->links_.push_back(*lit); } //old MarControlValue can and should now be safely deleted from memory delete oldvalue; //check if it's needed to call update() if(update) value_->callMarSystemsUpdate();//newvalue->callMarSystemsUpdate(); return true; }