Before everything, I've to say that I'm not very inside python programming as I am in other languages. I'm quite (too) annoyed for searching other ways of solution, so thank you in advance for your help.
I love to make Roguelike games in my free time, so I've tried numerous ways to do my own "engine" implementations and own engines for my own games using C++, C, C#, HTML5 etc. I've never worked before with LibTCOD because I never could make it work in C++ alas is my favourite programming language, that's an issue that I'm not going to talk right now for it's in C++ thread.
Awfully, LibTCOD looks great but has too few mentions and precise documentation, so I've to worked it almost alone. The last days I've done a little python package to easily manage LibTCOD functionality for python and windows, and make the main game code the tiniest possible.
The final implementation I tried to add is to pass the main game loop to a thread, handling every basic game functionality (like keyboard/mouse changes and screen update), and running it by a function call.
Everything works fine... but not after the first loop step, for it freezes everything and stops working.
Basically this is the problematic code:
def ioHandler(l):
lastx = 0
lasty = 0
lastk = None
c = 0
noEvent = 0
casted = False
while not tcod.console_is_window_closed():
l.acquire()
try:
tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS|tcod.EVENT_MOUSE,key,mouse)
finally:
l.release()
if mouse.lbutton_pressed:
casted = True
l.acquire()
try:
onClick(mouse, 'left')
finally:
l.release()
if mouse.rbutton_pressed:
casted = True
l.acquire()
try:
onClick(mouse, 'right')
finally:
l.release()
if mouse.cx != lastx or mouse.cy != lasty:
casted = True
l.acquire()
try:
lastx = mouse.cx
lasty = mouse.cy
onMouseMove(mouse)
finally:
l.release()
if key != lastk:
casted = True
l.acquire()
try:
lastk = key
onKeyPress(key)
finally:
l.release()
if not casted: noEvent += 1
l.acquire()
try:
onTickFrame(c+1)
finally:
l.release()
Most of the variables used there are for clearer debug understanding purpose, (even with the 'clean' function it froze) so I've to put those there.
The above 'def' is called from here:
def main_loop():
l = threading.Lock()
tr = threading.Thread(target=ioHandler, args=(l,))
#tr.daemon=True
tr.start()
For the 'Event' system, I've found this on internet:
class Event:
handlers = set()
def __init__(self):
self.handlers = set()
def handle(self, handler):
self.handlers.add(handler)
return self
def unhandle(self, handler):
try:
self.handlers.remove(handler)
except:
raise ValueError("Handler is not handling this event, so cannot unhandle it.")
return self
def fire(self, *args, **kargs):
for handler in self.handlers:
handler(*args, **kargs)
def getHandlerCount(self):
return len(self.handlers)
__iadd__ = handle
__isub__ = unhandle
__call__ = fire
__len__ = getHandlerCount
As a note: I'm working with Python 2.7, that's the only version that worked for the library, what a shame.
I think the event system may be the main problem. Reading the code again, I think I should apply a lock to the while condition too, therefore to the whole loop, or is that not necessary? Are the locks applied in the proper way? or should I use another methods to make the thread works?
Just to mention, everything works fine if the main game loop is doing on the main script without threads, but everything fails when called as a thread or even if it's not a thread itself but it's called from 'outside' as any other function in the package, so it can't be a library problem (I think).
I have to say, that I've only worked with LibTCOD in Python, as I can't make it work (at least on windows) only on it. If it helps, I've seen that the code for the python library is just a 'bind' for the original C library, so It's not a big deal to understand the python code. For the last statement, I think that's a problem for python threads too, or am I wrong? if there's something I can do to fix the thread implement, please help me!
Thank you all! I hope I have not bored you with my talk.