I'm trying to run a twisted-server with pygame-clients:
class ChatClientProtocol(LineReceiver):
def lineReceived(self,line):
print (line)
class ChatClient(ClientFactory):
def __init__(self):
self.protocol = ChatClientProtocol
def main():
flag = 0
default_screen()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
return
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
pos = pygame.mouse.get_pos()
# some rect.collidepoint(pos) rest of loop...
And here is the server:
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
class Chat(LineReceiver):
def __init__(self, users, players):
self.users = users
self.name = None
self.players = players
def connectionMade(self):
new = 'player_' + str(len(self.players) + 1)
self.players.append(new)
self.sendLine(str(self.players,))
class ChatFactory(Factory):
def __init__(self):
self.users = {} #maps instances to clients
self.players = []
def buildProtocol(self, addr):
return Chat(self.users,self.players)
reactor.listenTCP(6000, ChatFactory())
reactor.run()
I'm running this server with the client code with out the reactor.CallLater() method and pygames code and the client connects fine. Am I using the reactor method wrong or is there something structurally wrong with the pygames code? Any help would be appreciated.
So I don't know if the loop within the pygames bit ever breaks to call the reactor again?
You should not write your own main loop (with while
) when using twisted. twisted has to control the main loop, and pygame is flexible enough to not care about (it does not need its own loop).
You should put everything which is inside your main loop into a function, and shedule it with the twisted reactor by calling reactor.CallLater()
def main():
flag = 0
default_screen()
reactor.callLater(0.1, tick)
def tick():
for event in pygame.event.get():
if event.type == pygame.QUIT:
reactor.stop() # just stop somehow
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
reactor.stop() # just stop somehow
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
pos = pygame.mouse.get_pos()
# some stuff
reactor.callLater(0.1, tick)
This way, you ensure the reactor runs and can handle network events.
Here's a small working example of a client that will just render the last line recieved:
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
import pygame
class ChatClientProtocol(LineReceiver):
def __init__(self, recv):
self.recv = recv
def lineReceived(self,line):
self.recv(line)
class ChatClient(ClientFactory):
def __init__(self, recv):
self.protocol = ChatClientProtocol
self.recv = recv
def buildProtocol(self, addr):
return ChatClientProtocol(self.recv)
class Client(object):
def __init__(self):
self.line = 'no message'
pygame.init()
self.screen = pygame.display.set_mode((200, 200))
reactor.callLater(0.1, self.tick)
def new_line(self, line):
self.line = line
def tick(self):
self.screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
reactor.stop() # just stop somehow
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
reactor.stop() # just stop somehow
self.screen.blit(pygame.font.SysFont('mono', 12, bold=True).render(self.line, True, (0, 255, 0)), (20,20))
pygame.display.flip()
reactor.callLater(0.1, self.tick)
if __name__ == '__main__':
c = Client()
reactor.connectTCP('127.0.0.1',6000, ChatClient(c.new_line))
reactor.run()
Here's a simple example using LoopingCall
, as Glyph suggested (I left out the protocoll/factory classes as they're the same as above):
from twisted.internet.task import LoopingCall
class Client(object):
def __init__(self):
self.line = 'no message'
pygame.init()
self.screen = pygame.display.set_mode((200, 200))
def new_line(self, line):
self.line = line
def tick(self):
self.screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
reactor.stop() # just stop somehow
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
reactor.stop() # just stop somehow
self.screen.blit(pygame.font.SysFont('mono', 12, bold=True).render(self.line, True, (0, 255, 0)), (20,20))
pygame.display.flip()
if __name__ == '__main__':
c = Client()
lc = LoopingCall(c.tick)
lc.start(0.1)
reactor.connectTCP('127.0.0.1',6000, ChatClient(c.new_line))
reactor.run()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With