Swiftgram/submodules/TelegramUI/Sources/SharedVideoContextManager.swift
Peter Iakovlev e9a4a9347a Revert "Rename directories [skip ci]"
This reverts commit 789438a27450dcbdee6065ebf096198ed3b90fec
2020-03-01 10:06:51 +00:00

122 lines
3.5 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import SwiftSignalKit
class SharedVideoContext {
func dispose() {
}
}
private final class SharedVideoContextSubscriber {
let id: Int32
let priority: Int32
let update: (SharedVideoContext?) -> Void
var active: Bool = false
init(id: Int32, priority: Int32, update: @escaping (SharedVideoContext?) -> Void) {
self.id = id
self.priority = priority
self.update = update
}
}
private final class SharedVideoContextHolder {
private var nextId: Int32 = 0
private var subscribers: [SharedVideoContextSubscriber] = []
let context: SharedVideoContext
init(context: SharedVideoContext) {
self.context = context
}
var isEmpty: Bool {
return self.subscribers.isEmpty
}
func addSubscriber(priority: Int32, update: @escaping (SharedVideoContext?) -> Void) -> Int32 {
let id = self.nextId
self.nextId += 1
self.subscribers.append(SharedVideoContextSubscriber(id: id, priority: priority, update: update))
self.subscribers.sort(by: { lhs, rhs in
if lhs.priority != rhs.priority {
return lhs.priority < rhs.priority
}
return lhs.id < rhs.id
})
return id
}
func removeSubscriberAndUpdate(id: Int32) {
for i in 0 ..< self.subscribers.count {
if self.subscribers[i].id == id {
let subscriber = self.subscribers[i]
self.subscribers.remove(at: i)
if subscriber.active {
subscriber.update(nil)
self.update()
}
break
}
}
}
func update() {
for i in (0 ..< self.subscribers.count) {
if i == self.subscribers.count - 1 {
if !self.subscribers[i].active {
self.subscribers[i].active = true
self.subscribers[i].update(self.context)
}
} else {
if self.subscribers[i].active {
self.subscribers[i].active = false
self.subscribers[i].update(nil)
}
}
}
}
}
final class SharedVideoContextManager {
private var holders: [AnyHashable: SharedVideoContextHolder] = [:]
func attachSharedVideoContext(id: AnyHashable, priority: Int32, create: () -> SharedVideoContext, update: @escaping (SharedVideoContext?) -> Void) -> Int32 {
assert(Queue.mainQueue().isCurrent())
let holder: SharedVideoContextHolder
if let current = self.holders[id] {
holder = current
} else {
holder = SharedVideoContextHolder(context: create())
self.holders[id] = holder
}
let id = holder.addSubscriber(priority: priority, update: update)
holder.update()
return id
}
func detachSharedVideoContext(id: AnyHashable, index: Int32) {
assert(Queue.mainQueue().isCurrent())
if let holder = self.holders[id] {
holder.removeSubscriberAndUpdate(id: index)
if holder.isEmpty {
holder.context.dispose()
self.holders.removeValue(forKey: id)
}
}
}
func withSharedVideoContext(id: AnyHashable, _ f: (SharedVideoContext?) -> Void) {
if let holder = self.holders[id] {
f(holder.context)
} else {
f(nil)
}
}
}