Skip to content

Commit ccb467c

Browse files
Massive UI overhaul
1 parent bbde330 commit ccb467c

File tree

8 files changed

+664
-291
lines changed

8 files changed

+664
-291
lines changed

SwiftSplit.xcodeproj/xcshareddata/xcschemes/SwiftSplit.xcscheme

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
buildConfiguration = "Debug"
3535
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
3636
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37+
debugAsWhichUser = "root"
3738
launchStyle = "0"
3839
useCustomWorkingDirectory = "NO"
3940
ignoresPersistentStateOnLaunch = "NO"

SwiftSplit/AppDelegate.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
2121
// Insert code here to tear down your application
2222
}
2323

24+
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
25+
return true
26+
}
2427

2528
}
2629

SwiftSplit/Base.lproj/Main.storyboard

Lines changed: 341 additions & 110 deletions
Large diffs are not rendered by default.

SwiftSplit/CelesteEventGenerator.swift

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,4 @@
99
import Foundation
1010

1111
class CelesteEventGenerator {
12-
var scanner: CelesteScanner
13-
var autoSplitterInfo: AutoSplitterInfo = AutoSplitterInfo()
14-
15-
init(pid: pid_t) throws {
16-
scanner = try CelesteScanner(pid: pid)
17-
try scanner.findHeader()
18-
}
19-
20-
func updateInfo() throws -> [String] {
21-
if let info = try scanner.getInfo() {
22-
let events = getEvents(from: autoSplitterInfo, to: info)
23-
autoSplitterInfo = info
24-
return events
25-
} else {
26-
autoSplitterInfo = AutoSplitterInfo()
27-
return []
28-
}
29-
}
30-
31-
func getEvents(from old: AutoSplitterInfo, to new: AutoSplitterInfo) -> [String] {
32-
var events: [String] = []
33-
if new.level != old.level {
34-
events.append("\(old.level) > \(new.level)")
35-
}
36-
if new.chapterStarted && !old.chapterStarted {
37-
events.append("start chapter \(new.chapter)")
38-
}
39-
if !new.chapterStarted && old.chapterStarted && !old.chapterComplete {
40-
events.append("reset chapter")
41-
}
42-
if new.chapterComplete && !old.chapterComplete {
43-
events.append("complete chapter \(old.chapter)")
44-
}
45-
return events
46-
}
4712
}

SwiftSplit/CelesteSplitter.swift

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,124 @@
77
//
88

99
import Foundation
10+
11+
enum SplitterError: Error {
12+
case noHeader
13+
}
14+
/**
15+
Handles sending split commands based on state changes
16+
*/
17+
class CelesteSplitter {
18+
let scanner: CelesteScanner
19+
let server: LiveSplitServer
20+
var autoSplitterInfo: AutoSplitterInfo = AutoSplitterInfo()
21+
var routeConfig = RouteConfig(
22+
useFileTime: false,
23+
reset: "",
24+
route: []
25+
)
26+
27+
init(pid: pid_t, server: LiveSplitServer) throws {
28+
self.scanner = try CelesteScanner(pid: pid)
29+
self.server = server
30+
self.server.pauseGameTime() // make sure gameTimeRunning is accurate
31+
try scanner.findHeader()
32+
if scanner.headerSignature == nil {
33+
throw SplitterError.noHeader
34+
}
35+
}
36+
37+
private var gameTimeRunning = false
38+
private(set) var routeIndex = 0
39+
40+
func update() throws -> [String] {
41+
guard let info = try scanner.getInfo() else {
42+
autoSplitterInfo = AutoSplitterInfo()
43+
return []
44+
}
45+
let events = getEvents(from: autoSplitterInfo, to: info)
46+
autoSplitterInfo = info
47+
48+
if routeConfig.useFileTime {
49+
server.setGameTime(seconds: autoSplitterInfo.fileTime)
50+
} else {
51+
server.setGameTime(seconds: autoSplitterInfo.chapterTime)
52+
}
53+
if autoSplitterInfo.timerActive {
54+
if !gameTimeRunning {
55+
server.resumeGameTime()
56+
gameTimeRunning = true
57+
}
58+
} else if gameTimeRunning {
59+
server.pauseGameTime()
60+
gameTimeRunning = false
61+
}
62+
processEvents(events)
63+
return events
64+
}
65+
66+
func getEvents(from old: AutoSplitterInfo, to new: AutoSplitterInfo) -> [String] {
67+
var events: [String] = []
68+
if new.level != old.level && old.level != "" && new.level != "" {
69+
events.append("\(old.level) > \(new.level)")
70+
}
71+
if new.chapterStarted && !old.chapterStarted {
72+
events.append("start chapter \(new.chapter)")
73+
}
74+
if !new.chapterStarted && old.chapterStarted && !old.chapterComplete {
75+
events.append("reset chapter")
76+
}
77+
if new.chapterComplete && !old.chapterComplete {
78+
events.append("complete chapter \(old.chapter)")
79+
}
80+
return events
81+
}
82+
83+
func processEvents(_ events: [String]) {
84+
for event in events {
85+
print("Event: `\(event)`")
86+
if event == routeConfig.reset {
87+
server.reset()
88+
routeIndex = 0
89+
} else if routeIndex < routeConfig.route.count {
90+
let nextEvent = routeConfig.route[routeIndex]
91+
if event == nextEvent || "!\(event)" == nextEvent {
92+
if routeIndex == 0 {
93+
server.reset()
94+
server.start()
95+
} else if !nextEvent.starts(with: "!") {
96+
server.split()
97+
}
98+
routeIndex += 1
99+
if routeIndex == routeConfig.route.count {
100+
routeIndex = 0
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}
107+
108+
struct RouteConfig {
109+
let useFileTime: Bool
110+
let reset: String
111+
let route: [String]
112+
}
113+
114+
extension RouteConfig {
115+
init?(json: [String: Any]) {
116+
guard let useFileTime = json["useFileTime"] as? Bool,
117+
let reset = json["reset"] as? String,
118+
let route = json["route"] as? [String]
119+
else {
120+
return nil
121+
}
122+
self.useFileTime = useFileTime
123+
self.reset = reset
124+
self.route = route
125+
}
126+
127+
init() {
128+
self.init(useFileTime: false, reset: "", route: [])
129+
}
130+
}

SwiftSplit/Core/LiveSplitServer.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ class LiveSplitServerHandler: MultiClientWebSocketHandler {
1616
}
1717

1818
class LiveSplitServer {
19-
let handler = LiveSplitServerHandler()
20-
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
19+
private let handler = LiveSplitServerHandler()
20+
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
21+
var connectedClients: Int {
22+
get { handler.connectedClients }
23+
}
2124

2225
init(host: String, port: Int) throws {
2326

SwiftSplit/Core/MultiClientWebSocketServer.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class MultiClientWebSocketHandler: ChannelInboundHandler {
1919
private let channelsSyncQueue = DispatchQueue(label: "channelsQueue")
2020
private var channels: [ObjectIdentifier: Channel] = [:]
2121
private var awaitingClose: Set<ObjectIdentifier> = Set()
22+
var connectedClients: Int {
23+
get { channels.count }
24+
}
2225

2326
func handlerAdded(ctx: ChannelHandlerContext) {
2427
let channel = ctx.channel

0 commit comments

Comments
 (0)