무엇인가 일어났을 때 알려주는 것
protocol Invocable : class
{
func invoke(_ data: Any)
}
protocol Disposable
{
func dispose()
}
class Event<T>
{
typealias EventHandler = (T) -> ()
var eventHandlers = [Invocable]()
func raise(_ data: T)
{
for handler in eventHandlers
{
handler.invoke(data)
}
}
// (U) -> (T) -> ()
func addHandler<U: AnyObject>(
target: U,
handler: @escaping (U) -> EventHandler
) -> Disposable
{
let subscription = Subscription(target: target, handler: handler, event: self)
eventHandlers.append(subscription)
return subscription
}
}
class Subscription<T: AnyObject, U> : Invocable, Disposable
{
weak var target : T?
let handler : (T) -> (U) -> ()
let event: Event<U>
init(target: T?,
handler: @escaping (T) -> (U) -> (),
event: Event<U>
)
{
self.target = target
self.event = event
self.handler = handler
}
func invoke(_ data: Any)
{
if let t = target
{
handler(t)(data as! U)
}
}
func dispose()
{
event.eventHandlers = event.eventHandlers.filter { $0 as AnyObject? !== self }
}
}
class Person
{
// event
let fallsIll = Event<String>()
init(){}
func catchCold()
{
fallsIll.raise("400 Seoul Road")
}
}
class Demo
{
init()
{
let p = Person()
let sub = p.fallsIll.addHandler(
target: self, handler: Demo.callDoctor
)
p.catchCold()
sub.dispose()
p.catchCold()
}
func callDoctor(address: String)
{
print("We need a doctor at \(address)")
}
}
func main()
{
let _ = Demo()
}
class person
{
var age: Int = 0
{
willSet(newValue)
{
print("About to set age to \(newValue)")
}
didSet
{
print("We just Changed age from \(oldValue) to \(age)")
}
}
}
class demo
{
init()
{
let p = person()
p.age = 20
p.age = 22
}
}
func main()
{
let _ = demo()
}
class Human
{
private var oldCanVote = false
var age: Int = 0
{
willSet(newValue)
{
print("About to set age to \(newValue)")
oldCanVote = canVote
}
didSet
{
print("We just Changed age from \(oldValue) to \(age)")
if age != oldValue
{
propertyChanged.raise(("age", age))
}
if canVote != oldCanVote
{
//
propertyChanged.raise(("canVote", canVote))
}
}
}
var canVote: Bool
{
return age >= 16
}
let propertyChanged = Event<(String, Any)>()
}
final class RefBool
{
var value: Bool
init(_ value: Bool)
{
self.value = value
}
}
class Human2
{
private var _age : Int = 0
var age: Int
{
get { return age }
set(value)
{
if _age == value { return }
// cache
let oldCanVote = canVote
var cancelSet = RefBool(false)
propertyChanging.raise(("age", value, cancelSet))
if cancelSet.value
{
return
}
// assign & notify
_age = value
propertyChanged.raise(("age", _age))
if oldCanVote != canVote
{
propertyChanged.raise(("canVote", canVote))
}
}
}
var canVote: Bool
{
return age >= 16
}
let propertyChanged = Event<(String, Any)>()
let propertyChanging = Event<(String, Any, RefBool)>()
}
class Demo3
{
init()
{
// let h = Human()
// h.propertyChanged.addHandler(target: self, handler: Demo3.propChanged)
// h.age = 20
// h.age = 22
let h = Human2()
h.propertyChanged.addHandler(target: self, handler: Demo3.propChanged)
h.propertyChanging.addHandler(target: self, handler: Demo3.propChanging)
h.age = 20
h.age = 22
h.age = 12
}
func propChanging(args: (String, Any, RefBool))
{
if args.0 == "age" && (args.1 as! Int) < 14
{
print("Cannot allow to set the age < 14")
args.2.value = true
}
}
func propChanged(args: (String, Any))
{
if args.0 == "age"
{
print("Person's age has been changed to \(args.1)")
}
else if args.0 == "canVote"
{
print("Voting status has changed to \(args.1)")
}
}
}