1*acc1a190STomasz Sapeta // Copyright 2022-present 650 Industries. All rights reserved.
2*acc1a190STomasz Sapeta 
3*acc1a190STomasz Sapeta /**
4*acc1a190STomasz Sapeta  An enum that identifies lifecycle method types.
5*acc1a190STomasz Sapeta  */
6*acc1a190STomasz Sapeta internal enum ViewLifecycleMethodType {
7*acc1a190STomasz Sapeta   case didUpdateProps
8*acc1a190STomasz Sapeta }
9*acc1a190STomasz Sapeta 
10*acc1a190STomasz Sapeta /**
11*acc1a190STomasz Sapeta  Type-erased protocol for all view lifecycle methods.
12*acc1a190STomasz Sapeta  */
13*acc1a190STomasz Sapeta internal protocol AnyViewLifecycleMethod: AnyDefinition {
14*acc1a190STomasz Sapeta   /**
15*acc1a190STomasz Sapeta    Type of the lifecycle method.
16*acc1a190STomasz Sapeta    */
17*acc1a190STomasz Sapeta   var type: ViewLifecycleMethodType { get }
18*acc1a190STomasz Sapeta 
19*acc1a190STomasz Sapeta   /**
20*acc1a190STomasz Sapeta    Calls the lifecycle method for the given view.
21*acc1a190STomasz Sapeta    */
callAsFunctionnull22*acc1a190STomasz Sapeta   func callAsFunction(_ view: UIView)
23*acc1a190STomasz Sapeta }
24*acc1a190STomasz Sapeta 
25*acc1a190STomasz Sapeta /**
26*acc1a190STomasz Sapeta  Element of the view definition that represents a lifecycle method, such as `OnViewDidUpdateProps`.
27*acc1a190STomasz Sapeta  */
28*acc1a190STomasz Sapeta public final class ViewLifecycleMethod<ViewType: UIView>: AnyViewLifecycleMethod {
29*acc1a190STomasz Sapeta   /**
30*acc1a190STomasz Sapeta    The actual closure that gets called when the view signals an event in view's lifecycle.
31*acc1a190STomasz Sapeta    */
32*acc1a190STomasz Sapeta   let closure: (ViewType) -> Void
33*acc1a190STomasz Sapeta 
34*acc1a190STomasz Sapeta   let type: ViewLifecycleMethodType
35*acc1a190STomasz Sapeta 
36*acc1a190STomasz Sapeta   init(type: ViewLifecycleMethodType, closure: @escaping (ViewType) -> Void) {
37*acc1a190STomasz Sapeta     self.type = type
38*acc1a190STomasz Sapeta     self.closure = closure
39*acc1a190STomasz Sapeta   }
40*acc1a190STomasz Sapeta 
41*acc1a190STomasz Sapeta   func callAsFunction(_ view: UIView) {
42*acc1a190STomasz Sapeta     guard let view = view as? ViewType else {
43*acc1a190STomasz Sapeta       log.warn("Cannot call lifecycle method '\(type)', given view is not of type '\(ViewType.self)'")
44*acc1a190STomasz Sapeta       return
45*acc1a190STomasz Sapeta     }
46*acc1a190STomasz Sapeta     closure(view)
47*acc1a190STomasz Sapeta   }
48*acc1a190STomasz Sapeta }
49