From 733d08638d1b00953c585eb735a5e0c3a11fb1a7 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Mon, 20 Dec 2021 00:30:50 +0100 Subject: [PATCH] Control manager thread save with SourceCallbacks --- ControlManager.cpp | 69 +++++++++++++++++++++++++++++++++++++-------- ControlManager.h | 19 ++++--------- rsc/osc/vimix.tosc | Bin 863 -> 1822 bytes 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/ControlManager.cpp b/ControlManager.cpp index 9f5db54..e4153b7 100644 --- a/ControlManager.cpp +++ b/ControlManager.cpp @@ -36,6 +36,7 @@ #endif #define CONTROL_OSC_MSG "OSC: " +#define OSC_SEPARATOR '/' void Control::RequestListener::ProcessMessage( const osc::ReceivedMessage& m, const IpEndpointName& remoteEndpoint ) @@ -58,21 +59,41 @@ void Control::RequestListener::ProcessMessage( const osc::ReceivedMessage& m, if (address.size() == 3 && address.front().compare(APP_NAME) == 0 ){ // done with the first part of the OSC address address.pop_front(); - // execute next part of the OSC message + // + // Execute next part of the OSC message according to target + // std::string target = address.front(); std::string attribute = address.back(); - // Log target + // Log target: just print text in log window if ( target.compare(OSC_LOG) == 0 ) { if ( attribute.compare(OSC_LOG_INFO) == 0) Log::Info(CONTROL_OSC_MSG "received '%s' from %s", m.AddressPattern(), sender); } - // Output target + // Output target: concerns attributes of the rendering output else if ( target.compare(OSC_OUTPUT) == 0 ) { Control::manager().setOutputAttribute(attribute, m.ArgumentStream()); } - // Current source target + // ALL sources target: apply attribute to all sources of the session + else if ( target.compare(OSC_ALL) == 0 ) + { + // Loop over selected sources + for (SourceList::iterator it = Mixer::manager().session()->begin(); it != Mixer::manager().session()->end(); ++it) { + // attributes operate on current source + Control::manager().setSourceAttribute( *it, attribute, m.ArgumentStream()); + } + } + // Selected sources target: apply attribute to all sources of the selection + else if ( target.compare(OSC_SELECTED) == 0 ) + { + // Loop over selected sources + for (SourceList::iterator it = Mixer::selection().begin(); it != Mixer::selection().end(); ++it) { + // attributes operate on current source + Control::manager().setSourceAttribute( *it, attribute, m.ArgumentStream()); + } + } + // Current source target: apply attribute to the current sources else if ( target.compare(OSC_CURRENT) == 0 ) { // attributes to change current @@ -141,6 +162,7 @@ Control::~Control() receiver_->Break(); delete receiver_; } + } bool Control::init() @@ -169,11 +191,12 @@ void Control::terminate() receiver_->AsynchronousBreak(); } + void Control::setOutputAttribute(const std::string &attribute, osc::ReceivedMessageArgumentStream arguments) { try { - /// '/vimix/output/enable' or '/vimix/output/enable T' or '/vimix/output/enable F' + /// e.g. '/vimix/output/enable' or '/vimix/output/enable T' or '/vimix/output/enable F' if ( attribute.compare(OSC_OUTPUT_ENABLE) == 0) { bool on = true; if ( !arguments.Eos()) { @@ -181,7 +204,7 @@ void Control::setOutputAttribute(const std::string &attribute, } Settings::application.render.disabled = !on; } - /// '/vimix/output/disable' or '/vimix/output/disable T' or '/vimix/output/disable F' + /// e.g. '/vimix/output/disable' or '/vimix/output/disable T' or '/vimix/output/disable F' else if ( attribute.compare(OSC_OUTPUT_DISABLE) == 0) { bool on = true; if ( !arguments.Eos()) { @@ -189,7 +212,7 @@ void Control::setOutputAttribute(const std::string &attribute, } Settings::application.render.disabled = on; } - /// '/vimix/output/fading f 0.2' + /// e.g. '/vimix/output/fading f 0.2' else if ( attribute.compare(OSC_OUTPUT_FADING) == 0) { float fading = 0.f; arguments >> fading >> osc::EndMessage; @@ -220,21 +243,45 @@ void Control::setSourceAttribute(Source *target, const std::string &attribute, return; try { - /// '/vimix/current/play' or '/vimix/current/play T' or '/vimix/current/play F' + /// e.g. '/vimix/current/play' or '/vimix/current/play T' or '/vimix/current/play F' if ( attribute.compare(OSC_SOURCE_PLAY) == 0) { bool on = true; if ( !arguments.Eos()) { arguments >> on >> osc::EndMessage; } - target->play(on); + target->call( new SetPlay(on) ); } - /// '/vimix/current/pause' or '/vimix/current/pause T' or '/vimix/current/pause F' + /// e.g. '/vimix/current/pause' or '/vimix/current/pause T' or '/vimix/current/pause F' else if ( attribute.compare(OSC_SOURCE_PAUSE) == 0) { bool on = true; if ( !arguments.Eos()) { arguments >> on >> osc::EndMessage; } - target->play(!on); + target->call( new SetPlay(!on) ); + } + /// e.g. '/vimix/current/alpha f 0.3' + else if ( attribute.compare(OSC_SOURCE_ALPHA) == 0) { + float x = 0.f; + arguments >> x >> osc::EndMessage; + target->call( new SetAlpha(x) ); + } + /// e.g. '/vimix/current/transparency f 0.7' + else if ( attribute.compare(OSC_SOURCE_TRANSPARENCY) == 0) { + float x = 0.f; + arguments >> x >> osc::EndMessage; + target->call( new SetAlpha(1.f - x) ); + } + /// e.g. '/vimix/current/depth f 5.0' + else if ( attribute.compare(OSC_SOURCE_DEPTH) == 0) { + float x = 0.f; + arguments >> x >> osc::EndMessage; + target->call( new SetDepth(x) ); + } + /// e.g. '/vimix/current/translation ff 10.0 2.2' + else if ( attribute.compare(OSC_SOURCE_TRANSLATE) == 0) { + float x = 0.f, y = 0.f; + arguments >> x >> y >> osc::EndMessage; + target->call( new Translation( x, y), true ); } #ifdef CONTROL_DEBUG else { diff --git a/ControlManager.h b/ControlManager.h index 12b0656..c412a18 100644 --- a/ControlManager.h +++ b/ControlManager.h @@ -3,8 +3,6 @@ #include "NetworkToolkit.h" -#define OSC_SEPARATOR '/' - #define OSC_LOG "log" #define OSC_LOG_INFO "info" @@ -13,6 +11,8 @@ #define OSC_OUTPUT_DISABLE "disable" #define OSC_OUTPUT_FADING "fading" +#define OSC_ALL "all" +#define OSC_SELECTED "selected" #define OSC_CURRENT "current" #define OSC_CURRENT_NONE "none" #define OSC_CURRENT_NEXT "next" @@ -21,17 +21,9 @@ #define OSC_SOURCE_PLAY "play" #define OSC_SOURCE_PAUSE "pause" #define OSC_SOURCE_ALPHA "alpha" -#define OSC_SOURCE_ALPHA_XY "alphaXY" -#define OSC_SOURCE_ALPHA_X "alphaX" -#define OSC_SOURCE_ALPHA_Y "alphaY" -#define OSC_SOURCE_TRANSPARENT "transparency" -#define OSC_SOURCE_POSITION "position" -#define OSC_SOURCE_POSITION_X "positionX" -#define OSC_SOURCE_POSITION_Y "positionY" -#define OSC_SOURCE_SCALE "scale" -#define OSC_SOURCE_SCALE_X "scaleX" -#define OSC_SOURCE_SCALE_Y "scaleY" -#define OSC_SOURCE_ANGLE "angle" +#define OSC_SOURCE_TRANSPARENCY "transparency" +#define OSC_SOURCE_DEPTH "depth" +#define OSC_SOURCE_TRANSLATE "translate" class Session; class Source; @@ -77,6 +69,7 @@ private: static void listen(); RequestListener listener_; UdpListeningReceiveSocket *receiver_; + }; #endif // CONTROL_H diff --git a/rsc/osc/vimix.tosc b/rsc/osc/vimix.tosc index bce387c5778398d92076a12a46f9fdb070c4255d..cb65380efd9842483cbdf0fe826f23cfe36a35c6 100644 GIT binary patch literal 1822 zcmV+(2jTd5ob6q0bD}yF{=UD0`^omsRUiuD3}wgd%ihlPs$=cWc6Rndgs99?Z~}Ja z-`@lQU%;+LT4_yZT0;U)PQu}k=iy-W&+{ioct+T_J@=v_*QAPoT+_2`cYINK7~E8~ z%4b7&(AsXGV(6}CA>sDwq9Qd^wQeb(s!B?|D$B^MYEXsMrYTEi3p5lHqKXiNQ*=@J z+V4K}$iY+WO%V=krC=%&h4W3!3c)2tzZl zpECns!gDQj^l$$rH%USSd)2Q{2!1gAvhi&8rFd$bP4rxhix+KAS?vapTH^8a5Gc)Z2R^wJJMV%aWytY&3@_@YoLKQ zGbc;Pg-go;wKH++gR>FTdN+U$4ip zUrmC4y%ooPS|~X5GhKTxgnlNxw+j8pg-OUbo!HL=SU~L040wu>UyT1@8*>iCh-(5>;B-8&8XzI zQ=mZy&QiJNCtVR9WRbY=CWyzgCldGlO&ixP(G_dHbh~%g?aqr9&I>Sa#V|3thQ;N* zM5JVKl`>i_Q&XD_LK%n3f-*vgz^PM4siw5(Pr@8)s?-Ec5EDrG-4IBSh=%|q46>Q1 zht1-}!;@l=QwN5{^GBv3e{}8eJ@dypr+J*_ahk_z9;bQlm*$y^YoF7ZlG7PevrN@& zX_U^Wak4@SNV#;T-@dwS-@PfF$-tS2E{)h$t0(aMOHJvE9J3c$uE+ExDwTo1jImt| zx1~V$0h(sa0!1ffF!D5Vl?QCTdNh(Yf;82M)3oEHco3F0CAa)y3{1doh)-wZoGcZW zgi^9cew?{+=Ej*DXKsfww=%mOe?Z3{&>fx8-rRNDgHrKX00C0WCakKmY{ie~KttWe zXWRX9Cf}zFw5Dhc8K?;nt+f=OY3i~0XqJ}Gu%ENUWLaP?pss8`eO$EXI(TQY+-SyR zxh`o5TW+Onxpf@2yq)BJ&#vGP!h2-G%VqN!)0mMmMwNoeQ{u?<;zwroBcv_P&HV7T znCYiT#Z3QOX%!e+5Z6yECHXb9id~G%oEqQ6_B7ZoB+cAt6)bq}H`;PZn9mqlXJp^= zPl8~NgfrI*1Rpu0+G3eri#YbV5KNFu_7K+E=E8*_)uc>)nAVe}`zQMQX{G1hV%%r( z_D?|LWO>&<5U5n*>p MAM_ai1K8pBvK2$A9{>OV literal 863 zcmV-l1EBnPoaI>2ZrU&u{T24a6H7u1rIK+)fp(QTKr~F7sy-OU1gjxNwnO3XXPYEI z!aAB})28x3uCL>BkL{CV0=QZ)g35|;L0Q$siADZDY3590)LOdjVj652NBFuRfaK_PstK0+%;ROsolbjw-fudO` z#wiIUl1kX6P-Bq{XqcPkDLbC$w#9moo1oCTm1yjt?ve0yMOShte zPV+N8ie>Fvi0KyTBXIyKS%l|1$gOhpOyeld^vDcFf$T<{D>>}?GkM@`+j~zX3dELj z+7$<*C74ojf)o|ALP-cb zB#~p*%mk)gPug`=A;rz8GAZ-mb_Q-z;b8xF+b=K*$X6O_+%%4}NFADuB&`}*Ng3d~ zL9hS)okf0E<6Gx`(mz^beR`4l#j!G}^sKGon80t5o&68XZi(bve=F-k!7o&yFycQH z;DbB98{8V$B$YkqtrcC+wWSWlWh5<+3Y3^=eB+xoI%Q^UnIi5-3*{*yOZs5@_vl>@ phxh%?;8n`&66oy_vy48holjZ%g#qfPHhF_cGUo3Z_!C-RF&6{Zsb&BG