I'm working on an editor for Bevy games and wanted the following workflow:
- Launch the game process
- Host a Metal view for the game's render target
- Use an XPC service to transfer an
MTLSharedTextureHandle - Keep the connection for editor/game communication and hot reload
As such I created the following editor service:
public let XPCEditorServiceName = "org.bevy.editor"
public enum XPCEditorMessage: Codable {
case ping
}
public enum XPCEditorReply: Codable {
case pong
}
extension XPCListener {
static let bevy = try! XPCListener(service: XPCEditorServiceName) { request in
request.accept(XPCEditorService.init)
}
}
struct XPCEditorService: XPCPeerHandler {
let session: XPCSession
private func handle(_ message: XPCEditorMessage) -> XPCEditorReply? {
switch message {
case .ping:
return .pong
}
}
func handleIncomingRequest(_ message: XPCReceivedMessage) -> (any Encodable)? {
do {
return handle(try message.decode())
} catch {
return nil
}
}
func handleCancellation(error: XPCRichError) {
print(error)
}
}
and I initialize it in my app's App initializer:
// Launch the XPC service
print(XPCListener.bevy)
I wanted to test this using an executable target with the following main.swift:
let session = try XPCSession(xpcService: XPCEditorServiceName)
let response: XPCEditorReply = try session.sendSync(XPCEditorMessage.ping)
print("Connected to editor!")
The editor prints Listener<org.bevy.editor>(Active) but the game fails with Underlying connection was invalidated. Reason: Connection init failed at lookup with error 3 - No such process
What am I doing wrong?
PS. Would also appreciate an example of sending & rendering the MTLSharedTextureHandle both in editor & game.