foo recalc not working

This commit is contained in:
jaseg 2016-05-29 04:02:35 +02:00
parent 7ab239d492
commit 38de96de6d
2 changed files with 119 additions and 57 deletions

155
clippy.py
View file

@ -11,12 +11,15 @@ import os
import functools import functools
import contextlib import contextlib
import math import math
import ctypes import threading
from PIL import Image from PIL import Image
from pixelterm import pixelterm from pixelterm import pixelterm
import pxf
from misc import resize_image
HOST, PORT = "172.23.42.29",2342 HOST, PORT = "172.23.42.29",2342
CMD_LED_DRAW = 18 CMD_LED_DRAW = 18
@ -59,32 +62,6 @@ class Display:
def encode_image(img, displaysize): def encode_image(img, displaysize):
return np.frombuffer(Display.do_gamma(resize_image(img, displaysize), 0.5).convert('1').tobytes(), dtype='1b') return np.frombuffer(Display.do_gamma(resize_image(img, displaysize), 0.5).convert('1').tobytes(), dtype='1b')
class Pixelflut:
def __init__(self, host, port, x, y, w, h, reps):
self.host, self.port = host.encode(), port
self.x, self.y = x, y
self.w, self.h = w, h
self.reps = reps
self.dbuf = np.zeros(w*h*4, dtype=np.uint8)
self.so = ctypes.CDLL('./pixelflut.so')
self.sock = None
def sendframe(self, idx):
for _ in range(self.reps):
if self.sock is None:
while self.sock is None or self.sock < 0:
time.sleep(1)
self.sock = self.so.cct(self.host, self.port)
if self.so.sendframe(self.sock, idx, self.w, self.h, self.x, self.y):
self.so.discct(self.sock)
self.sock = None
def encode_image(self, img):
frame = np.array(resize_image(img, (self.w, self.h), blackbg=False)).reshape(self.w*self.h*4)
np.copyto(self.dbuf, frame)
cptr = self.dbuf.ctypes.data_as(ctypes.POINTER(ctypes.c_uint8))
return self.so.store_image(cptr, self.w, self.h)
def weightedChoice(choices, default=None): def weightedChoice(choices, default=None):
acc = 0 acc = 0
r = random.random() r = random.random()
@ -164,7 +141,9 @@ if __name__ == '__main__':
parser.add_argument('-a', '--agent', default='Clippy') parser.add_argument('-a', '--agent', default='Clippy')
parser.add_argument('-e', '--endless', action='store_true') parser.add_argument('-e', '--endless', action='store_true')
parser.add_argument('-d', '--display', action='store_true') parser.add_argument('-d', '--display', action='store_true')
parser.add_argument('-p', '--pixelflut', type=str, default='94.45.232.225:1234') parser.add_argument('-i', '--interactive', action='store_true')
parser.add_argument('-w', '--wait', type=int, default=120)
parser.add_argument('-p', '--pixelflut', type=str)
parser.add_argument('-t', '--terminal', action='store_true') parser.add_argument('-t', '--terminal', action='store_true')
parser.add_argument('-x', '--termsize', type=str) parser.add_argument('-x', '--termsize', type=str)
parser.add_argument('-s', '--socket', action='store_true') parser.add_argument('-s', '--socket', action='store_true')
@ -173,10 +152,13 @@ if __name__ == '__main__':
parser.add_argument('action', default='Greeting', nargs='?') parser.add_argument('action', default='Greeting', nargs='?')
args = parser.parse_args() args = parser.parse_args()
agent_path = pathlib.Path('agents') / args.agent agent_paths = []
if not agent_path.is_dir(): for agent in args.agent.split(','):
print('Agent not found. Exiting.') agent_path = pathlib.Path('agents') / agent
sys.exit(1) if not agent_path.is_dir():
print('Agent "{}" not found. Exiting.'.format(agent))
sys.exit(1)
agent_paths.append(agent_path)
if args.list: if args.list:
print('\n'.join(Agent(agent_path).animations)) print('\n'.join(Agent(agent_path).animations))
@ -191,18 +173,71 @@ if __name__ == '__main__':
x, y, *_r = params[0].split(',') if params else (0, 0, None) x, y, *_r = params[0].split(',') if params else (0, 0, None)
w, h, reps = _r if _r else (320, 240) w, h, reps = _r if _r else (320, 240)
x, y, w, h, reps = map(int, (x, y, w, h, reps)) x, y, w, h, reps = map(int, (x, y, w, h, reps))
pf = Pixelflut(host, port, x, y, w, h, reps) if args.pixelflut else None pf = pxf.Pixelflut(host, port, x, y, w, h, reps) if args.pixelflut else None
else: else:
pf = None pf = None
agent = Agent(agent_path) agents = []
if args.socket: for path in agent_paths:
tx, ty = (args.termsize or '60x30').split('x') agent = Agent(path)
tx, ty = int(tx), int(ty) if args.socket:
elif args.terminal: tx, ty = (args.termsize or '60x30').split('x')
tx, ty = args.termsize.split('x') or os.get_terminal_size() tx, ty = int(tx), int(ty)
tx, ty = int(tx), int(ty) elif args.terminal:
termsize = (tx, ty*2) if args.terminal or args.socket else None tx, ty = args.termsize.split('x') or os.get_terminal_size()
agent.precalculate_images(pf, dsp, termsize) tx, ty = int(tx), int(ty)
termsize = (tx, ty*2) if args.terminal or args.socket else None
agent.precalculate_images(pf, dsp, termsize)
agents.append(agent)
runlock = threading.Lock()
ts = time.time()
if args.interactive:
from tkinter import *
def recalc_size(delta):
global runlock
with runlock:
print('resetting')
pf.reset_images()
pf.w += delta
pf.h += delta
print('recalcing')
for agent in Agents:
agent.precalculate_images(pf, dsp, termsize)
def keyfunc(ev):
global ts
ch = ev.char
if ch == '+':
recalc_size(50)
elif ch == '-':
recalc_size(-50)
if ch == 'w':
pf.y -= 10
elif ch == 'a':
pf.x -= 10
elif ch == 's':
pf.y += 10
elif ch == 'd':
pf.x += 10
elif ch == 'e':
pf.reps += 1
elif ch == 'q':
if pf.reps > 1:
pf.reps -= 1
elif ch == 'n':
ts = time.time() - args.wait - 1
def tkrun():
tkr = Tk()
tkf = Frame(tkr, width=100, height=100)
tkf.bind('<Key>', keyfunc)
tkf.pack()
tkf.focus_set()
tkr.mainloop()
tkrunner = threading.Thread(target=tkrun, daemon=True)
tkrunner.start()
if args.socket: if args.socket:
import socketserver import socketserver
@ -211,6 +246,7 @@ if __name__ == '__main__':
class ClippyRequestHandler(socketserver.BaseRequestHandler): class ClippyRequestHandler(socketserver.BaseRequestHandler):
def handle(self): def handle(self):
with contextlib.suppress(BrokenPipeError): with contextlib.suppress(BrokenPipeError):
agent = random.choice(agents)
while True: while True:
action = random.choice(agent.animations) action = random.choice(agent.animations)
print('[\033[38;5;245m{}\033[0m] Playing: {}'.format(self.client_address[0], action)) print('[\033[38;5;245m{}\033[0m] Playing: {}'.format(self.client_address[0], action))
@ -222,20 +258,29 @@ if __name__ == '__main__':
server.serve_forever() server.serve_forever()
elif args.endless: elif args.endless:
while True: while True:
if random.random() > 0.2: print('Starting', ts)
action = random.choice(agent.animations) for agent in agents:
print('Playing:', action) while time.time() - ts < args.wait:
for img_pf, img_dsp, img_term in agent(action, not args.nosleep): if random.random() > 0.2:
if args.terminal: action = random.choice(agent.animations)
print('\033[H'+img_term) print('Playing:', action)
if args.display: for img_pf, img_dsp, img_term in agent(action, not args.nosleep):
dsp.sendframe(img_dsp) with runlock:
if args.pixelflut: if args.terminal:
pf.sendframe(img_pf) print('\033[H'+img_term)
if not args.nosleep: if args.display:
time.sleep(1) dsp.sendframe(img_dsp)
if args.pixelflut:
pf.sendframe(img_pf)
if time.time() - ts > args.wait:
print('Force-advance', ts)
break
if not args.nosleep:
time.sleep(1)
print('Advancing', ts)
ts = time.time()
else: else:
for img_pf, img_dsp, img_term in agent(args.action, not args.nosleep): for img_pf, img_dsp, img_term in agents[0](args.action, not args.nosleep):
if args.terminal: if args.terminal:
print(pixelterm.termify_pixels( print(pixelterm.termify_pixels(
resize_image(img, termsize))) resize_image(img, termsize)))

View file

@ -20,6 +20,24 @@ int store_image(const uint8_t *img, int w, int h) {
return image_count++; return image_count++;
} }
int store_image_idx(const uint8_t *img, int w, int h, int idx) {
if (idx >= sizeof(images)/sizeof(images[0]))
return -1;
if (images[idx])
free(images[idx]);
images[idx] = malloc(w*h*4);
memcpy(images[idx], img, w*h*4);
return 0;
}
void reset_images() {
for (int i=0; i<image_count; i++) {
free(images[i]);
images[i] = NULL;
}
image_count = 0;
}
#define PIXEL_FORMAT "PX %zd %zd %02x%02x%02x\n" #define PIXEL_FORMAT "PX %zd %zd %02x%02x%02x\n"
int cct(const char *target, int port) { int cct(const char *target, int port) {
printf("Reconnecting %s:%d\n", target, port); printf("Reconnecting %s:%d\n", target, port);
@ -48,7 +66,7 @@ int cct(const char *target, int port) {
int sendframe(int fd, int idx, int w, int h, int ox, int oy) { int sendframe(int fd, int idx, int w, int h, int ox, int oy) {
static unsigned long fcnt=0; static unsigned long fcnt=0;
printf("frame %lu %dx%d @pos %dx%d\n", fcnt++, w, h, ox, oy); // printf("frame %lu %dx%d @pos %dx%d\n", fcnt++, w, h, ox, oy);
int fmtlen = snprintf(NULL, 0, PIXEL_FORMAT, (size_t)1000, (size_t)1000, 0xff, 0xff, 0xff); int fmtlen = snprintf(NULL, 0, PIXEL_FORMAT, (size_t)1000, (size_t)1000, 0xff, 0xff, 0xff);
char *out = malloc(1400); char *out = malloc(1400);
if (!out) { if (!out) {
@ -74,7 +92,6 @@ int sendframe(int fd, int idx, int w, int h, int ox, int oy) {
} }
} }
free(out); free(out);
usleep(1000);
return 0; return 0;
} }