给 Swift 写 Event Emitter,有什么优雅的方法吗?

2014-07-02 07:38:19 +08:00
 notcome
尝试把 Swift 打造成服务端语言,昨天已经搞完了 Hiredis 同步 API 的绑定,该出手处理异步 API 了。

如题,感觉注册事件还比较容易,用枚举可以很好的完成抽象,但是 on 函数就要手动编写了。如果使用数组存 listener 的话,还可以 map……

就是 on 不能自动化好不爽有木有。

求思路
3412 次点击
所在节点    iDev
6 条回复
hewigovens
2014-07-02 08:42:35 +08:00
听上去是redis swift client?
notcome
2014-07-02 09:06:59 +08:00
@hewigovens 是的,封装了 Hiredis,已经被 C 指针玩死了 Swift 把 char[] 当 tuple 处理你造吗……
notcome
2014-07-02 09:09:10 +08:00
@hewigovens 目标是用 Swift 写服务器端代码,我想类似模板引擎这样的东西反正也能用 JavaScriptCore 解决(虽然不兼容 CommonJS 但比重写好多了……吧!),于是就去试试。

没有类型系统的日子我已经受!够!了!
notcome
2014-07-02 09:10:13 +08:00
不过说实话,发 iDev 不合适……不过估计这里的人对 Swift 最熟了。
notcome
2014-07-02 11:53:53 +08:00
class EEProto {
var A: Int
var B: Double

typealias EventChangeA = (Int, Int) -> Void
typealias EventChangeB = (Double, Double) -> Void
typealias EventChanged = () -> Void

struct RegisteredEvent {
var eventChangeA: EventChangeA[]
var eventChangeB: EventChangeB[]
var eventChanged: EventChanged[]
}

enum EventType {
case changeA(EventChangeA[])
case changeB(EventChangeB[])
case changed(EventChanged[])
}

var registeredEvents: RegisteredEvent

init (A: Int, B: Double) {
self.A = A
self.B = B
registeredEvents = RegisteredEvent(eventChangeA: [], eventChangeB: [], eventChanged: [])
}

func on (event: EventType) {
switch event {
case .changeA(let events):
registeredEvents.eventChangeA += events
case .changeB(let events):
registeredEvents.eventChangeB += events
case .changed(let events):
registeredEvents.eventChanged += events
default:
assert("unhandled event type | check your code")
break
}
}

func resetEvents (eventType: EventType) {
switch eventType {
case .changeA:
registeredEvents.eventChangeA = []
case .changeB:
registeredEvents.eventChangeA = []
case .changed:
registeredEvents.eventChangeA = []
default:
assert("unhandled event type | check your code")
break
}
}

func setA (newA: Int) {
let oldA = A
A = newA
for cb in registeredEvents.eventChangeA {
cb(oldA, newA)
}
for cb in registeredEvents.eventChanged {
cb()
}
}

func setB (newB: Double) {
let oldB = B
B = newB
for cb in registeredEvents.eventChangeB {
cb(oldB, newB)
}
for cb in registeredEvents.eventChanged {
cb()
}
}
}

var inst = EEProto(A: 10, B: 5.5)
inst.on(EEProto.EventType.changeA([{
println("from \($0) to \($1)")
}]))
inst.on(EEProto.EventType.changeB([{
println("from \($0) to \($1)")
}]))
inst.on(EEProto.EventType.changed([{
println("value changed")
}]))

inst.setA(10)
inst.setB(3.14)

好冗余………………丑爆了。
notcome
2014-07-02 11:54:46 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/120517

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX