5 type TIPCMessage = record |
5 type TIPCMessage = record |
6 str: shortstring; |
6 str: shortstring; |
7 len: Longword; |
7 len: Longword; |
8 buf: Pointer |
8 buf: Pointer |
9 end; |
9 end; |
|
10 TIPCCallback = procedure (p: pointer; s: shortstring); |
10 |
11 |
11 var msgFrontend, msgEngine: TIPCMessage; |
12 var msgFrontend, msgEngine: TIPCMessage; |
12 mutFrontend, mutEngine: PSDL_mutex; |
13 mutFrontend, mutEngine: PSDL_mutex; |
13 condFrontend, condEngine: PSDL_cond; |
14 condFrontend, condEngine: PSDL_cond; |
14 |
15 |
15 procedure initIPC; |
16 procedure initIPC; |
16 procedure freeIPC; |
17 procedure freeIPC; |
17 |
18 |
18 procedure ipcToEngine(s: shortstring); |
19 procedure ipcToEngine(s: shortstring); cdecl; export; |
19 function ipcReadFromEngine: shortstring; |
20 function ipcReadFromEngine: shortstring; |
20 function ipcCheckFromEngine: boolean; |
21 function ipcCheckFromEngine: boolean; |
21 |
22 |
22 procedure ipcToFrontend(s: shortstring); |
23 procedure ipcToFrontend(s: shortstring); |
23 function ipcReadFromFrontend: shortstring; |
24 function ipcReadFromFrontend: shortstring; |
24 function ipcCheckFromFrontend: boolean; |
25 function ipcCheckFromFrontend: boolean; |
25 |
26 |
|
27 procedure registerIPCCallback(p: pointer; f: TIPCCallback); cdecl; export; |
|
28 |
26 implementation |
29 implementation |
|
30 |
|
31 var callbackPointer: pointer; |
|
32 callbackFunction: TIPCCallback; |
|
33 callbackListenerThread: PSDL_Thread; |
27 |
34 |
28 procedure ipcSend(var s: shortstring; var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond); |
35 procedure ipcSend(var s: shortstring; var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond); |
29 begin |
36 begin |
30 SDL_LockMutex(mut); |
37 SDL_LockMutex(mut); |
|
38 writeln(stdout, 'ipc send', s); |
31 while (msg.str[0] > #0) or (msg.buf <> nil) do |
39 while (msg.str[0] > #0) or (msg.buf <> nil) do |
32 SDL_CondWait(cond, mut); |
40 SDL_CondWait(cond, mut); |
33 |
41 |
34 msg.str:= s; |
42 msg.str:= s; |
35 SDL_CondSignal(cond); |
43 SDL_CondSignal(cond); |
36 SDL_UnlockMutex(mut) |
44 SDL_UnlockMutex(mut); |
|
45 writeln(stdout, 'ipc sent', s[1]) |
37 end; |
46 end; |
38 |
47 |
39 function ipcRead(var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond): shortstring; |
48 function ipcRead(var msg: TIPCMessage; mut: PSDL_mutex; cond: PSDL_cond): shortstring; |
40 begin |
49 begin |
41 SDL_LockMutex(mut); |
50 SDL_LockMutex(mut); |
42 while (msg.str[0] = #0) and (msg.buf = nil) do |
51 while (msg.str[0] = #0) and (msg.buf = nil) do |
43 SDL_CondWait(cond, mut); |
52 SDL_CondWait(cond, mut); |
44 |
53 |
45 ipcRead:= msg.str; |
54 ipcRead:= msg.str; |
|
55 writeln(stdout, 'engine ipc received', msg.str[1]); |
46 msg.str[0]:= #0; |
56 msg.str[0]:= #0; |
47 if msg.buf <> nil then |
57 if msg.buf <> nil then |
48 begin |
58 begin |
49 FreeMem(msg.buf, msg.len); |
59 FreeMem(msg.buf, msg.len); |
50 msg.buf:= nil |
60 msg.buf:= nil |
59 SDL_LockMutex(mut); |
69 SDL_LockMutex(mut); |
60 ipcCheck:= (msg.str[0] > #0) or (msg.buf <> nil); |
70 ipcCheck:= (msg.str[0] > #0) or (msg.buf <> nil); |
61 SDL_UnlockMutex(mut) |
71 SDL_UnlockMutex(mut) |
62 end; |
72 end; |
63 |
73 |
64 procedure ipcToEngine(s: shortstring); |
74 procedure ipcToEngine(s: shortstring); cdecl; export; |
65 begin |
75 begin |
66 ipcSend(s, msgEngine, mutEngine, condEngine) |
76 ipcSend(s, msgEngine, mutEngine, condEngine) |
67 end; |
77 end; |
68 |
78 |
69 procedure ipcToFrontend(s: shortstring); |
79 procedure ipcToFrontend(s: shortstring); |
89 function ipcCheckFromFrontend: boolean; |
99 function ipcCheckFromFrontend: boolean; |
90 begin |
100 begin |
91 ipcCheckFromFrontend:= ipcCheck(msgEngine, mutEngine) |
101 ipcCheckFromFrontend:= ipcCheck(msgEngine, mutEngine) |
92 end; |
102 end; |
93 |
103 |
|
104 function listener(p: pointer): Longint; cdecl; export; |
|
105 begin |
|
106 listener:= 0; |
|
107 repeat |
|
108 callbackFunction(callbackPointer, ipcReadFromEngine()) |
|
109 until false |
|
110 end; |
|
111 |
|
112 procedure registerIPCCallback(p: pointer; f: TIPCCallback); cdecl; export; |
|
113 begin |
|
114 callbackPointer:= p; |
|
115 callbackFunction:= f; |
|
116 callbackListenerThread:= SDL_CreateThread(@listener{$IFDEF SDL2}, 'ipcListener'{$ENDIF}, nil); |
|
117 end; |
|
118 |
94 procedure initIPC; |
119 procedure initIPC; |
95 begin |
120 begin |
96 msgFrontend.str:= ''; |
121 msgFrontend.str:= ''; |
97 msgFrontend.buf:= nil; |
122 msgFrontend.buf:= nil; |
98 msgEngine.str:= ''; |
123 msgEngine.str:= ''; |
99 msgEngine.buf:= nil; |
124 msgEngine.buf:= nil; |
|
125 |
|
126 callbackPointer:= nil; |
|
127 callbackListenerThread:= nil; |
100 |
128 |
101 mutFrontend:= SDL_CreateMutex; |
129 mutFrontend:= SDL_CreateMutex; |
102 mutEngine:= SDL_CreateMutex; |
130 mutEngine:= SDL_CreateMutex; |
103 condFrontend:= SDL_CreateCond; |
131 condFrontend:= SDL_CreateCond; |
104 condEngine:= SDL_CreateCond; |
132 condEngine:= SDL_CreateCond; |
105 end; |
133 end; |
106 |
134 |
107 procedure freeIPC; |
135 procedure freeIPC; |
108 begin |
136 begin |
|
137 SDL_KillThread(callbackListenerThread); |
109 SDL_DestroyMutex(mutFrontend); |
138 SDL_DestroyMutex(mutFrontend); |
110 SDL_DestroyMutex(mutEngine); |
139 SDL_DestroyMutex(mutEngine); |
111 SDL_DestroyCond(condFrontend); |
140 SDL_DestroyCond(condFrontend); |
112 SDL_DestroyCond(condEngine); |
141 SDL_DestroyCond(condEngine); |
113 end; |
142 end; |