interface AttachableVideoView { attachEngine(engine: Engine): void; detachEngine(): void; } interface VideoViewAttachmentState { view: AttachableVideoView | null; engine: Engine | null; } export function createVideoViewAttachmentState< Engine >(): VideoViewAttachmentState { return { view: null, engine: null, }; } export function detachVideoView( state: VideoViewAttachmentState ): void { if (state.view != null && state.engine != null) { state.view.detachEngine(); } state.view = null; state.engine = null; } export function syncVideoViewAttachment( state: VideoViewAttachmentState, nextView: AttachableVideoView | null, nextEngine: Engine | undefined ): void { if ( state.view != null && (state.view !== nextView || state.engine !== nextEngine) ) { detachVideoView(state); } if ( nextView != null && nextEngine != null && (state.view !== nextView || state.engine !== nextEngine) ) { nextView.attachEngine(nextEngine); state.view = nextView; state.engine = nextEngine; } }