20
20
#pragma once
21
21
22
22
#include < ableton/discovery/Service.hpp>
23
- #include < ableton/link/CircularFifo.hpp>
24
23
#include < ableton/link/ClientSessionTimelines.hpp>
25
24
#include < ableton/link/Gateway.hpp>
26
25
#include < ableton/link/GhostXForm.hpp>
@@ -317,24 +316,19 @@ class Controller
317
316
// This flag ensures that mRtClientState is only updated after all incoming
318
317
// client states were processed
319
318
mHasPendingRtClientStates = true ;
320
- // This will fail in case the Fifo in the RtClientStateSetter is full. This indicates
321
- // a very high rate of calls to the setter. In this case we ignore one value because
322
- // we expect the setter to be called again soon.
323
- if (mRtClientStateSetter . tryPush ( newClientState) )
319
+ mRtClientStateSetter . push (newClientState);
320
+ const auto now = mClock . micros ();
321
+ // Cache the new timeline and StartStopState for serving back to the client
322
+ if (newClientState. timeline )
324
323
{
325
- const auto now = mClock .micros ();
326
324
// Cache the new timeline and StartStopState for serving back to the client
327
- if (newClientState.timeline )
328
- {
329
- // Cache the new timeline and StartStopState for serving back to the client
330
- mRtClientState .timeline = *newClientState.timeline ;
331
- mRtClientState .timelineTimestamp = makeRtTimestamp (now);
332
- }
333
- if (newClientState.startStopState )
334
- {
335
- mRtClientState .startStopState = *newClientState.startStopState ;
336
- mRtClientState .startStopStateTimestamp = makeRtTimestamp (now);
337
- }
325
+ mRtClientState .timeline = *newClientState.timeline ;
326
+ mRtClientState .timelineTimestamp = makeRtTimestamp (now);
327
+ }
328
+ if (newClientState.startStopState )
329
+ {
330
+ mRtClientState .startStopState = *newClientState.startStopState ;
331
+ mRtClientState .startStopStateTimestamp = makeRtTimestamp (now);
338
332
}
339
333
}
340
334
@@ -581,14 +575,23 @@ class Controller
581
575
{
582
576
}
583
577
584
- bool tryPush (const IncomingClientState clientState)
578
+ void push (const IncomingClientState clientState)
585
579
{
586
- const auto success = mClientStateFifo .push (clientState);
587
- if (success)
580
+ if (clientState.timeline )
581
+ {
582
+ mTimelineBuffer .write (
583
+ std::make_pair (clientState.timelineTimestamp , *clientState.timeline ));
584
+ }
585
+
586
+ if (clientState.startStopState )
587
+ {
588
+ mStartStopStateBuffer .write (*clientState.startStopState );
589
+ }
590
+
591
+ if (clientState.timeline || clientState.startStopState )
588
592
{
589
593
mCallbackDispatcher .invoke ();
590
594
}
591
- return success;
592
595
}
593
596
594
597
void processPendingClientStates ()
@@ -601,27 +604,23 @@ class Controller
601
604
IncomingClientState buildMergedPendingClientState ()
602
605
{
603
606
auto clientState = IncomingClientState{};
604
- while ( const auto result = mClientStateFifo . pop ())
607
+ if ( auto tl = mTimelineBuffer . readNew ())
605
608
{
606
- if (result->timeline )
607
- {
608
- clientState.timeline = result->timeline ;
609
- clientState.timelineTimestamp = result->timelineTimestamp ;
610
- }
611
- if (result->startStopState )
612
- {
613
- clientState.startStopState = result->startStopState ;
614
- }
609
+ clientState.timelineTimestamp = (*tl).first ;
610
+ clientState.timeline = OptionalTimeline{(*tl).second };
611
+ }
612
+ if (auto sss = mStartStopStateBuffer .readNew ())
613
+ {
614
+ clientState.startStopState = sss;
615
615
}
616
616
return clientState;
617
617
}
618
618
619
619
Controller& mController ;
620
- // Assuming a wake up time of one ms for the threads owned by the CallbackDispatcher
621
- // and the ioService, buffering 16 client states allows to set eight client states
622
- // per ms.
623
- static const std::size_t kBufferSize = 16 ;
624
- CircularFifo<IncomingClientState, kBufferSize > mClientStateFifo ;
620
+ // Use separate TripleBuffers for the Timeline and the StartStopState so we read the
621
+ // latest set value from either optional.
622
+ TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer ;
623
+ TripleBuffer<ClientStartStopState> mStartStopStateBuffer ;
625
624
CallbackDispatcher mCallbackDispatcher ;
626
625
};
627
626
0 commit comments