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
|
||||
*.marm
|
||||
*.marm.*
|
||||
*.so
|
|
@ -35,6 +35,7 @@ rgcolorFg.extend([col | FBRIGHT for col in range(8)])
|
|||
K_BACKSPACE = chr(8)
|
||||
K_TAB = chr(9)
|
||||
K_RETURN = chr(10)
|
||||
K_NEWLINE = chr(13)
|
||||
K_DEL = chr(127)
|
||||
K_LEFT = 256
|
||||
K_RIGHT = 257
|
||||
|
|
|
@ -131,7 +131,7 @@ class Terminal(Token):
|
|||
elif (ansi.FKeyPrintable(key)):
|
||||
self.stLine = self.stLine[:self.x - self.xLine] + key + self.stLine[(self.x + 1) - self.xLine:]
|
||||
self.moveTo(self.x + 1, self.y)
|
||||
elif key == ansi.K_RETURN:
|
||||
elif key == ansi.K_RETURN or key == ansi.K_NEWLINE:
|
||||
break
|
||||
else:
|
||||
print "weird key", ansi.StrKey(key)
|
||||
|
|
14
haxor.py
14
haxor.py
|
@ -45,13 +45,13 @@ class IntroTerm(Terminal):
|
|||
self.newLine()
|
||||
self.client.quit()
|
||||
|
||||
class Haxor(object):
|
||||
def __init__(self):
|
||||
self.game = GmSimple([AutoJoiner, IntroTerm])
|
||||
class HaxorGame(Game):
|
||||
def GetRgclsTokTrans(self):
|
||||
return [[AutoJoiner, IntroTerm]]
|
||||
|
||||
class HaxorRunner(Runner):
|
||||
def RunGame(self, client):
|
||||
client.joinGame(self.game)
|
||||
def RunServer(self):
|
||||
telnet.RunServer(self.RunGame)
|
||||
client.joinGame(HaxorGame())
|
||||
|
||||
if __name__ == "__main__":
|
||||
Haxor().RunServer()
|
||||
HaxorRunner().RunServer()
|
||||
|
|
|
@ -671,7 +671,7 @@ class PwButton(PwStatic):
|
|||
def ColFg(self):
|
||||
return ansi.BLUE | ansi.FBRIGHT
|
||||
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)
|
||||
return True
|
||||
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