77
88#include " Scheduler.h"
99
10+ #include " SchedulerDelegateRegistration.h"
11+
1012#include < glog/logging.h>
1113#include < jsi/jsi.h>
1214
@@ -36,7 +38,27 @@ Scheduler::Scheduler(
3638 const SchedulerToolbox& schedulerToolbox,
3739 UIManagerAnimationDelegate* animationDelegate,
3840 SchedulerDelegate* delegate)
39- : runtimeExecutor_(schedulerToolbox.runtimeExecutor),
41+ : Scheduler(
42+ schedulerToolbox,
43+ animationDelegate,
44+ std::make_shared<SchedulerDelegateRegistration>(delegate)) {}
45+
46+ Scheduler::Scheduler (
47+ const SchedulerToolbox& schedulerToolbox,
48+ UIManagerAnimationDelegate* animationDelegate,
49+ std::shared_ptr<SchedulerDelegate> delegate)
50+ : Scheduler(
51+ schedulerToolbox,
52+ animationDelegate,
53+ std::make_shared<SchedulerDelegateRegistration>(
54+ std::move (delegate))) {}
55+
56+ Scheduler::Scheduler (
57+ const SchedulerToolbox& schedulerToolbox,
58+ UIManagerAnimationDelegate* animationDelegate,
59+ std::shared_ptr<SchedulerDelegateRegistration> delegateRegistration)
60+ : delegateRegistration_(std::move(delegateRegistration)),
61+ runtimeExecutor_(schedulerToolbox.runtimeExecutor),
4062 contextContainer_(schedulerToolbox.contextContainer) {
4163 // Creating a container for future `EventDispatcher` instance.
4264 eventDispatcher_ = std::make_shared<std::optional<const EventDispatcher>>();
@@ -156,7 +178,6 @@ Scheduler::Scheduler(
156178 std::weak_ptr<const ComponentDescriptorRegistry>(
157179 componentDescriptorRegistry_));
158180
159- delegate_ = delegate;
160181 commitHooks_ = schedulerToolbox.commitHooks ;
161182
162183 // Layout events (`onLayout`) are emitted as a standalone consumer of the
@@ -185,6 +206,8 @@ Scheduler::Scheduler(
185206}
186207
187208Scheduler::~Scheduler () {
209+ std::atomic_load (&delegateRegistration_)->retire ();
210+
188211 LOG (WARNING ) << " Scheduler::~Scheduler() was called (address: " << this
189212 << " )." ;
190213
@@ -278,11 +301,23 @@ Scheduler::findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
278301#pragma mark - Delegate
279302
280303void Scheduler::setDelegate (SchedulerDelegate* delegate) {
281- delegate_ = delegate;
304+ replaceDelegate (std::make_shared<SchedulerDelegateRegistration>(delegate));
305+ }
306+
307+ void Scheduler::setOwnedDelegate (std::shared_ptr<SchedulerDelegate> delegate) {
308+ replaceDelegate (
309+ std::make_shared<SchedulerDelegateRegistration>(std::move (delegate)));
310+ }
311+
312+ void Scheduler::replaceDelegate (
313+ std::shared_ptr<SchedulerDelegateRegistration> delegateRegistration) {
314+ auto previous = std::atomic_exchange (
315+ &delegateRegistration_, std::move (delegateRegistration));
316+ previous->retire ();
282317}
283318
284319SchedulerDelegate* Scheduler::getDelegate () const {
285- return delegate_ ;
320+ return std::atomic_load (&delegateRegistration_)-> acquire (). get () ;
286321}
287322
288323#pragma mark - UIManagerAnimationDelegate
@@ -301,29 +336,32 @@ void Scheduler::uiManagerDidFinishTransaction(
301336 bool mountSynchronously) {
302337 TraceSection s (" Scheduler::uiManagerDidFinishTransaction" );
303338
304- if (delegate_ != nullptr ) {
339+ auto registration = std::atomic_load (&delegateRegistration_);
340+ if (auto delegate = registration->acquire ()) {
305341 // This is no-op on all platforms except for Android where we need to
306342 // observe each transaction to be able to mount correctly.
307- delegate_ ->schedulerDidFinishTransaction (mountingCoordinator);
343+ delegate ->schedulerDidFinishTransaction (mountingCoordinator);
308344
309345 if (!mountSynchronously) {
310346 auto surfaceId = mountingCoordinator->getSurfaceId ();
311347
312348 runtimeScheduler_->scheduleRenderingUpdate (
313349 surfaceId,
314- [delegate = delegate_ ,
350+ [registration = std::move (registration) ,
315351 mountingCoordinator = std::move (mountingCoordinator)]() {
316- delegate->schedulerShouldRenderTransactions (mountingCoordinator);
352+ if (auto delegate = registration->acquire ()) {
353+ delegate->schedulerShouldRenderTransactions (mountingCoordinator);
354+ }
317355 });
318356 } else {
319- delegate_ ->schedulerShouldRenderTransactions (mountingCoordinator);
357+ delegate ->schedulerShouldRenderTransactions (mountingCoordinator);
320358 }
321359 }
322360}
323361
324362void Scheduler::uiManagerDidCreateShadowNode (const ShadowNode& shadowNode) {
325- if (delegate_ != nullptr ) {
326- delegate_ ->schedulerDidRequestPreliminaryViewAllocation (shadowNode);
363+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
364+ delegate ->schedulerDidRequestPreliminaryViewAllocation (shadowNode);
327365 }
328366}
329367
@@ -333,15 +371,19 @@ void Scheduler::uiManagerDidDispatchCommand(
333371 const folly::dynamic& args) {
334372 TraceSection s (
335373 " Scheduler::uiManagerDispatchCommand" , " commandName" , commandName);
336- if (delegate_ != nullptr ) {
374+ auto registration = std::atomic_load (&delegateRegistration_);
375+ if (registration->acquire ()) {
337376 auto shadowView = ShadowView (*shadowNode);
338377 runtimeScheduler_->scheduleRenderingUpdate (
339378 shadowNode->getSurfaceId (),
340- [delegate = delegate_ ,
379+ [registration = std::move (registration) ,
341380 shadowView = std::move (shadowView),
342381 commandName,
343382 args]() {
344- delegate->schedulerDidDispatchCommand (shadowView, commandName, args);
383+ if (auto delegate = registration->acquire ()) {
384+ delegate->schedulerDidDispatchCommand (
385+ shadowView, commandName, args);
386+ }
345387 });
346388 }
347389}
@@ -351,9 +393,9 @@ void Scheduler::uiManagerDidSendAccessibilityEvent(
351393 const std::string& eventType) {
352394 TraceSection s (" Scheduler::uiManagerDidSendAccessibilityEvent" );
353395
354- if (delegate_ != nullptr ) {
396+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
355397 auto shadowView = ShadowView (*shadowNode);
356- delegate_ ->schedulerDidSendAccessibilityEvent (shadowView, eventType);
398+ delegate ->schedulerDidSendAccessibilityEvent (shadowView, eventType);
357399 }
358400}
359401
@@ -364,45 +406,45 @@ void Scheduler::uiManagerDidSetIsJSResponder(
364406 const std::shared_ptr<const ShadowNode>& shadowNode,
365407 bool isJSResponder,
366408 bool blockNativeResponder) {
367- if (delegate_ != nullptr ) {
368- delegate_ ->schedulerDidSetIsJSResponder (
409+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
410+ delegate ->schedulerDidSetIsJSResponder (
369411 ShadowView (*shadowNode), isJSResponder, blockNativeResponder);
370412 }
371413}
372414
373415void Scheduler::uiManagerShouldSynchronouslyUpdateViewOnUIThread (
374416 Tag tag,
375417 const folly::dynamic& props) {
376- if (delegate_ != nullptr ) {
377- delegate_ ->schedulerShouldSynchronouslyUpdateViewOnUIThread (tag, props);
418+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
419+ delegate ->schedulerShouldSynchronouslyUpdateViewOnUIThread (tag, props);
378420 }
379421}
380422
381423void Scheduler::uiManagerDidUpdateShadowTree (
382424 const std::unordered_map<Tag, folly::dynamic>& tagToProps) {
383- if (delegate_ != nullptr ) {
384- delegate_ ->schedulerDidUpdateShadowTree (tagToProps);
425+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
426+ delegate ->schedulerDidUpdateShadowTree (tagToProps);
385427 }
386428}
387429
388430void Scheduler::uiManagerDidCaptureViewSnapshot (Tag tag, SurfaceId surfaceId) {
389- if (delegate_ != nullptr ) {
390- delegate_ ->schedulerDidCaptureViewSnapshot (tag, surfaceId);
431+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
432+ delegate ->schedulerDidCaptureViewSnapshot (tag, surfaceId);
391433 }
392434}
393435
394436void Scheduler::uiManagerDidSetViewSnapshot (
395437 Tag sourceTag,
396438 Tag targetTag,
397439 SurfaceId surfaceId) {
398- if (delegate_ != nullptr ) {
399- delegate_ ->schedulerDidSetViewSnapshot (sourceTag, targetTag, surfaceId);
440+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
441+ delegate ->schedulerDidSetViewSnapshot (sourceTag, targetTag, surfaceId);
400442 }
401443}
402444
403445void Scheduler::uiManagerDidClearPendingSnapshots () {
404- if (delegate_ != nullptr ) {
405- delegate_ ->schedulerDidClearPendingSnapshots ();
446+ if (auto delegate = std::atomic_load (&delegateRegistration_)-> acquire () ) {
447+ delegate ->schedulerDidClearPendingSnapshots ();
406448 }
407449}
408450
@@ -417,13 +459,21 @@ void Scheduler::uiManagerShouldRemoveEventListener(
417459}
418460
419461void Scheduler::uiManagerDidFinishReactCommit (const ShadowTree& shadowTree) {
420- if (delegate_ == nullptr ) {
462+ auto registration = std::atomic_load (&delegateRegistration_);
463+ if (!registration->acquire ()) {
421464 return ;
422465 }
423466
424467 auto surfaceId = shadowTree.getSurfaceId ();
425468 runtimeScheduler_->scheduleRenderingUpdate (
426- surfaceId, [surfaceId, uiManager = uiManager_, delegate = delegate_]() {
469+ surfaceId,
470+ [surfaceId,
471+ uiManager = uiManager_,
472+ registration = std::move (registration)]() {
473+ auto delegate = registration->acquire ();
474+ if (!delegate) {
475+ return ;
476+ }
427477 bool promoted = false ;
428478
429479 uiManager->getShadowTreeRegistry ().visit (
0 commit comments