Skip to content

Commit

Permalink
Fix Windows IPC stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
John Novak committed Jul 15, 2024
1 parent 9ed76ac commit 687d01c
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 79 deletions.
3 changes: 2 additions & 1 deletion src/appevents.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import std/strutils
import std/times
import std/typedthreads

import glfw
import semver

import common

when defined(windows):
import platform/windows/ipc

# {{{ macFileOpener()
when defined(macosx):
Expand Down
155 changes: 77 additions & 78 deletions src/platform/windows/ipc.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import std/options
import std/os
import std/strformat
import std/typedthreads

Expand Down Expand Up @@ -32,12 +33,21 @@ proc displayError(msg: string) =

# }}}

# {{{ isAppRunning()
proc isAppRunning(): bool =
discard CreateMutex(nil, true, "Global\\Gridmonger")
result = GetLastError() == ErrorAlreadyExists
# {{{ commonInit()
proc commonInit(): bool =
g_overlapped.hEvent = CreateEvent(
nil, # default security attribute
true, # manual-reset event
true, # initial state = signaled
nil # unnamed event object
)
if g_overlapped.hEvent == 0:
displayError(fmt"CreateEvent failed, error code: {GetLastError()}")
else:
result = true

# }}}

# {{{ sendMessage()
proc sendMessage(numBytes: int32) =
discard WriteFile(
Expand All @@ -51,24 +61,64 @@ proc sendMessage(numBytes: int32) =
WaitForSingleObject(g_overlapped.hEvent, 2000)

# }}}
# {{{ commonInit()
proc commonInit(): bool =
g_overlapped.hEvent = CreateEvent(
nil, # default security attribute
true, # manual-reset event
true, # initial state = signaled
nil # unnamed event object
)
if g_overlapped.hEvent == 0:
displayError(fmt"CreateEvent failed, error code: {GetLastError()}")
else:
result = true
# {{{ sendFocusMessage()
proc sendFocusMessage() =
g_buffer[0] = aeFocus.byte
sendMessage(numBytes=1)

# }}}
# {{{ sendOpenFileMessage()
proc sendOpenFileMessage(path: string) =
var path = path.substr(0, MaxPathLen-1)
g_buffer[0] = aeOpenFile.byte
cast[ptr int16](g_buffer[1].addr)[] = path.len.int16
copyMem(g_buffer[3].addr, path[0].addr, path.len)

sendMessage(numBytes=path.len.int32 + 3)

# }}}

# {{{ eventPoller()
import platform/windows/ipc
# {{{ tryRecv()
proc tryRecv(): Option[AppEvent] =
discard ConnectNamedPipe(g_pipe, g_overlapped.addr)

if ReadFile(g_pipe, g_buffer[0].addr, g_buffer.len.int32, nil,
g_overlapped.addr) == 0:
case GetLastError()
of ErrorBrokenPipe:
# Client has disconnected; disconnect pipe so ConnectNamedPipe can
# succeed in the next iteration, allowing another client to
# connect
discard DisconnectNamedPipe(g_pipe)
else:
# echo fmt"Cannot connect to named pipe, error code: {GetLastError()}"
discard

# Because the last `wait` arg is set to false, this will only succeed
# when the message has been fully read into the buffer
var numBytesTransferred: int32
if GetOverlappedResult(g_pipe, g_overlapped.addr,
numBytesTransferred.addr, false) == 0:

# echo fmt"Error getting overlapped result, error code: {GetLastError()}"
discard
else:
let eventKind = cast[AppEventKind](g_buffer[0])
var event = AppEvent(kind: eventKind)

case event.kind
of aeFocus: discard
of aeOpenFile:
let length = cast[ptr int16](g_buffer[1].addr)[]
event.path = newString(length)
copyMem(event.path[0].addr, g_buffer[3].addr, length)
else:
echo fmt"Unexpected event: {event}"

result = event.some

# }}}
# {{{ eventPoller()
type
IpcEventPollerMsg = enum
ipmShutdown
Expand All @@ -83,14 +133,20 @@ proc eventPoller() {.thread.} =
if dataAvailable and msg == ipmShutdown:
break

let appEvent = ipc.tryRecv()
let appEvent = tryRecv()
if appEvent.isSome:
sendAppEvent(appEvent.get)

sleep(100)

# }}}

# {{{ isAppRunning*()
proc isAppRunning*(): bool =
discard CreateMutex(nil, true, "Global\\Gridmonger")
result = GetLastError() == ErrorAlreadyExists

# }}}
# {{{ initClient*()
proc initClient*(): bool =
if not commonInit():
Expand Down Expand Up @@ -118,23 +174,6 @@ proc initClient*(): bool =
result = true

# }}}
# {{{ sendFocusMessage*()
proc sendFocusMessage*() =
g_buffer[0] = aeFocus.byte
sendMessage(numBytes=1)

# }}}
# {{{ sendOpenFileMessage*()
proc sendOpenFileMessage*(path: string) =
var path = path.substr(0, MaxPathLen-1)
g_buffer[0] = aeOpenFile.byte
cast[ptr int16](g_buffer[1].addr)[] = path.len.int16
copyMem(g_buffer[3].addr, path[0].addr, path.len)

sendMessage(numBytes=path.len.int32 + 3)

# }}}

# {{{ initServer*()
proc initServer*(): bool =
if not commonInit():
Expand All @@ -156,8 +195,8 @@ proc initServer*(): bool =
displayError(fmt"Cannot create named pipe, error code: {GetLastError()}")
return false

g_winIpcEventPollerCh.open
createThread(g_winIpcEventPollerThr, winIpcEventPoller)
g_eventPollerCh.open
createThread(g_eventPollerThr, eventPoller)
result = true

# }}}
Expand All @@ -169,46 +208,6 @@ proc shutdownServer*() =

discard CloseHandle(g_pipe)

# }}}
# {{{ tryRecv*()
proc tryRecv*(): Option[AppEvent] =
discard ConnectNamedPipe(g_pipe, g_overlapped.addr)

if ReadFile(g_pipe, g_buffer[0].addr, g_buffer.len.int32, nil,
g_overlapped.addr) == 0:
case GetLastError()
of ErrorBrokenPipe:
# Client has disconnected; disconnect pipe so ConnectNamedPipe can
# succeed in the next iteration, allowing another client to
# connect
discard DisconnectNamedPipe(g_pipe)
else:
# echo fmt"Cannot connect to named pipe, error code: {GetLastError()}"
discard

# Because the last `wait` arg is set to false, this will only succeed
# when the message has been fully read into the buffer
var numBytesTransferred: int32
if GetOverlappedResult(g_pipe, g_overlapped.addr,
numBytesTransferred.addr, false) == 0:

# echo fmt"Error getting overlapped result, error code: {GetLastError()}"
discard
else:
let eventKind = cast[AppEventKind](g_buffer[0])
var event = AppEvent(kind: eventKind)

case event.kind
of aeFocus: discard
of aeOpenFile:
let length = cast[ptr int16](g_buffer[1].addr)[]
event.path = newString(length)
copyMem(event.path[0].addr, g_buffer[3].addr, length)
else:
echo fmt"Unexpected event: {event}"

result = event.some

# }}}

# {{{ Test
Expand Down

0 comments on commit 687d01c

Please sign in to comment.