Port to greenlet; nix-based dev environment
This commit is contained in:
parent
5ddee41d8a
commit
04963f4512
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,3 +8,4 @@ build
|
||||||
*.h
|
*.h
|
||||||
*.marm
|
*.marm
|
||||||
*.marm.*
|
*.marm.*
|
||||||
|
*.so
|
|
@ -35,6 +35,7 @@ rgcolorFg.extend([col | FBRIGHT for col in range(8)])
|
||||||
K_BACKSPACE = chr(8)
|
K_BACKSPACE = chr(8)
|
||||||
K_TAB = chr(9)
|
K_TAB = chr(9)
|
||||||
K_RETURN = chr(10)
|
K_RETURN = chr(10)
|
||||||
|
K_NEWLINE = chr(13)
|
||||||
K_DEL = chr(127)
|
K_DEL = chr(127)
|
||||||
K_LEFT = 256
|
K_LEFT = 256
|
||||||
K_RIGHT = 257
|
K_RIGHT = 257
|
||||||
|
|
|
@ -131,7 +131,7 @@ class Terminal(Token):
|
||||||
elif (ansi.FKeyPrintable(key)):
|
elif (ansi.FKeyPrintable(key)):
|
||||||
self.stLine = self.stLine[:self.x - self.xLine] + key + self.stLine[(self.x + 1) - self.xLine:]
|
self.stLine = self.stLine[:self.x - self.xLine] + key + self.stLine[(self.x + 1) - self.xLine:]
|
||||||
self.moveTo(self.x + 1, self.y)
|
self.moveTo(self.x + 1, self.y)
|
||||||
elif key == ansi.K_RETURN:
|
elif key == ansi.K_RETURN or key == ansi.K_NEWLINE:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print "weird key", ansi.StrKey(key)
|
print "weird key", ansi.StrKey(key)
|
||||||
|
|
14
haxor.py
14
haxor.py
|
@ -45,13 +45,13 @@ class IntroTerm(Terminal):
|
||||||
self.newLine()
|
self.newLine()
|
||||||
self.client.quit()
|
self.client.quit()
|
||||||
|
|
||||||
class Haxor(object):
|
class HaxorGame(Game):
|
||||||
def __init__(self):
|
def GetRgclsTokTrans(self):
|
||||||
self.game = GmSimple([AutoJoiner, IntroTerm])
|
return [[AutoJoiner, IntroTerm]]
|
||||||
|
|
||||||
|
class HaxorRunner(Runner):
|
||||||
def RunGame(self, client):
|
def RunGame(self, client):
|
||||||
client.joinGame(self.game)
|
client.joinGame(HaxorGame())
|
||||||
def RunServer(self):
|
|
||||||
telnet.RunServer(self.RunGame)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
Haxor().RunServer()
|
HaxorRunner().RunServer()
|
||||||
|
|
|
@ -671,7 +671,7 @@ class PwButton(PwStatic):
|
||||||
def ColFg(self):
|
def ColFg(self):
|
||||||
return ansi.BLUE | ansi.FBRIGHT
|
return ansi.BLUE | ansi.FBRIGHT
|
||||||
def HandleKey(self, pov, psel, key):
|
def HandleKey(self, pov, psel, key):
|
||||||
if key == ansi.K_RETURN:
|
if key == ansi.K_RETURN or key == ansi.K_NEWLINE:
|
||||||
self.dgEnter(self.Value(), psel)
|
self.dgEnter(self.Value(), psel)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
11
shell.nix
Normal file
11
shell.nix
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
let
|
||||||
|
pkgs = import <nixpkgs> {};
|
||||||
|
pyenv = pypkgs: with pypkgs; [
|
||||||
|
greenlet twisted cython mysqlclient bcrypt
|
||||||
|
];
|
||||||
|
in
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
(pkgs.python2.withPackages pyenv)
|
||||||
|
];
|
||||||
|
}
|
85
stackless.py
Normal file
85
stackless.py
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
from greenlet import greenlet
|
||||||
|
import traceback
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
class Scheduler(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.running = None
|
||||||
|
self.rgtasklet = []
|
||||||
|
self.g = None
|
||||||
|
|
||||||
|
def schedule(self, tasklet, *args):
|
||||||
|
tasklet.args = args
|
||||||
|
tasklet.scheduled = True
|
||||||
|
self.rgtasklet.append(tasklet)
|
||||||
|
|
||||||
|
def kill(self, tasklet):
|
||||||
|
if not tasklet.g.dead:
|
||||||
|
tasklet.g.parent = greenlet.getcurrent()
|
||||||
|
tasklet.g.throw()
|
||||||
|
try:
|
||||||
|
self.rgtasklet.remove(tasklet)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.g = greenlet.getcurrent()
|
||||||
|
while len(self.rgtasklet) > 0:
|
||||||
|
tasklets = self.rgtasklet
|
||||||
|
self.rgtasklet = []
|
||||||
|
for tasklet in tasklets:
|
||||||
|
try:
|
||||||
|
self.running = tasklet
|
||||||
|
args = tasklet.args
|
||||||
|
tasklet.args = None
|
||||||
|
tasklet.scheduled = False
|
||||||
|
tasklet.g.parent = self.g
|
||||||
|
tasklet.g.switch(*args)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
self.kill(tasklet)
|
||||||
|
self.running = None
|
||||||
|
self.g = None
|
||||||
|
|
||||||
|
def suspend(self):
|
||||||
|
self.g.switch()
|
||||||
|
|
||||||
|
class Tasklet(object):
|
||||||
|
def __init__(self, cb, scheduler):
|
||||||
|
self.g = greenlet(cb)
|
||||||
|
self.args = None
|
||||||
|
self.scheduler = scheduler
|
||||||
|
self.scheduled = False
|
||||||
|
|
||||||
|
def __call__(self, *args):
|
||||||
|
self.scheduler.schedule(self, *args)
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
self.scheduler.kill(self)
|
||||||
|
|
||||||
|
class Channel(object):
|
||||||
|
def __init__(self, scheduler):
|
||||||
|
self.queue = deque()
|
||||||
|
self.tasklet = None
|
||||||
|
self.scheduler = scheduler
|
||||||
|
|
||||||
|
def receive(self):
|
||||||
|
while len(self.queue) == 0:
|
||||||
|
self.tasklet = self.scheduler.running
|
||||||
|
self.tasklet.scheduled = True
|
||||||
|
self.scheduler.suspend()
|
||||||
|
self.tasklet = None
|
||||||
|
return self.queue.popleft()
|
||||||
|
|
||||||
|
def send(self, val):
|
||||||
|
self.queue.append(val)
|
||||||
|
if self.tasklet:
|
||||||
|
self.scheduler.schedule(self.tasklet)
|
||||||
|
|
||||||
|
scheduler = Scheduler()
|
||||||
|
def tasklet(cb):
|
||||||
|
return Tasklet(cb, scheduler)
|
||||||
|
def channel():
|
||||||
|
return Channel(scheduler)
|
||||||
|
def run():
|
||||||
|
scheduler.run()
|
Loading…
Reference in a new issue