Im trying to create a little 2D game engine using Unicurses. To do so, I have created a Player base class, which handles all the keystrokes and communicates them to the main program via a pipe. To get the keystrokes I use the unicurses.wgetch(screen) function, which requires a reference to the screen created by the unicurses.initscr() function. This reference however is a ctypes.c_void_p
, which cant be pickled, and thus raises an exeption when i try to create a subprocess (using the multiprocessing module) executing the main function of the Player class.
Here an example code that produces the exact same error while somewhat keeping the structure of my program
import multiprocessing as mp
import unicurses as curses
from typing import Type
from multiprocessing.connection import PipeConnection
class playerbase():
def __init__(self) -> None:
#do something
...
def _handshake(self, pipe:PipeConnection):
self.pipe = pipe
def init(self, screen):
self.scr = screen
#do other things
def start(self):
key = curses.wgetch(scr_id=self.scr)
#do something
class engine():
def __init__(self, player: Type[playerbase] = playerbase):
self.player = player()
def mainloop(self): #gets called by the main program to start the rendering and stuff
In, Out = mp.Pipe()
self.player._handshake(Out)
self.loop(In, self.player) #I originally intended to make this a subprocess
def loop(self, pipe:PipeConnection, player):
stdscr = curses.initscr()
player.init(stdscr)
PProc = mp.Process(target=player.start, args=())
PProc.start()
def main():
e = engine()
e.mainloop()
if __name__ == "__main__":
main()
This produces the following error:
Traceback (most recent call last):
File "[FILEPATH]", line 38, in <module>
main()
File "[FILEPATH]", line 36, in main
e.mainloop()
File "[FILEPATH]", line 26, in mainloop
self.loop(In, self.player) #I originally intended to make this a subprocess
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[FILEPATH]", line 32, in loop
PProc.start()
File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\process.py", line 121, in start
self._popen = self._Popen(self)
^^^^^^^^^^^^^^^^^
File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\context.py", line 336, in _Popen
return Popen(process_obj)
^^^^^^^^^^^^^^^^^^
File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\popen_spawn_win32.py", line 94, in __init__
reduction.dump(process_obj, to_child)
File "C:\Users\[USER]\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
ValueError: ctypes objects containing pointers cannot be pickled