Finished full client to web stack, works fine

master
cyrille 2013-09-30 23:32:09 +02:00
parent e760498b3b
commit 581bcd71e9
5 changed files with 208 additions and 97 deletions

View File

@ -12,7 +12,7 @@ local_port = 5001
# UDP webserver port to bypass frameserver for testing # UDP webserver port to bypass frameserver for testing
remote_port = 4422 remote_port = 4422
# port to frameserver # port to frameserver
#remote_port = 4321 remote_port = 4321
# TODO: autodetect interface address for remote application # TODO: autodetect interface address for remote application
outgoing_if = "127.0.0.1" outgoing_if = "127.0.0.1"
@ -56,6 +56,9 @@ frequency = 1000 / sleeptime # frames per second
# function resets map to zero # function resets map to zero
def set_wdata(r, g, b): def set_wdata(r, g, b):
global wdata
wdata = []
for x in xrange(width): for x in xrange(width):
wdata.append([0] * height) wdata.append([0] * height)
for y in xrange(height): for y in xrange(height):
@ -80,6 +83,21 @@ def i2c(rgba):
# ignore rgba[0] because it is the state # ignore rgba[0] because it is the state
return chr(int(rgba[1])) + chr(int(rgba[2])) + chr(int(rgba[3])) + chr(int(rgba[4])) return chr(int(rgba[1])) + chr(int(rgba[2])) + chr(int(rgba[3])) + chr(int(rgba[4]))
# determine if a cells neighbour is active (any will do)
def has_active_neighb(x, y):
# check the cell to the left
if x > 0 and wdata[x - 1][y][0] > 0:
return True
# check the cell above
if y > 0 and wdata[x][y - 1][0] > 0:
return True
# check the cell to the right
if x < (width - 1) and wdata[x + 1][y][0] > 0:
return True
# check the cell below
if y < (height - 1) and wdata[x][y + 1][0] > 0:
return True
# function sends wdata and sdata state to server # function sends wdata and sdata state to server
def send_update(): def send_update():
#zero out the data buffer #zero out the data buffer
@ -105,101 +123,75 @@ def send_update():
# send the data packet to remote host # send the data packet to remote host
UDPSock.sendto(data,(remote_host,remote_port)) UDPSock.sendto(data,(remote_host,remote_port))
# initialize map # main loop
set_wdata(67,67,67) while True:
set_sdata(0,0,255) # reset/initialize map
set_wdata(67,67,67)
set_sdata(255,255,255)
# set start seed # set start seed
# get random location # get random location
rx = randint(0, width - 1) rx = randint(0, width - 1)
ry = randint(0, height - 1) ry = randint(0, height - 1)
wdata[rx][ry] = [1,1,0,0,1] wdata[rx][ry] = [1,1,0,0,1]
print "origin(" + str(rx) + "," + str(ry) + ")" # print "origin(" + str(rx) + "," + str(ry) + ")"
def has_active_neighb(x, y): # main logic loop
# check the cell to the left for t in range(23):
if x > 0 and wdata[x - 1][y][0] > 0:
return True
# check the cell above
if y > 0 and wdata[x][y - 1][0] > 0:
return True
# check the cell to the right
if x < (width - 1) and wdata[x + 1][y][0] > 0:
return True
# check the cell below
if y < (height - 1) and wdata[x][y + 1][0] > 0:
return True
# main logic loop # push update to clients
for t in range(60): send_update()
# push update to clients # create CA buffer
send_update() data_buffer = deepcopy(wdata)
# create CA buffer for y in xrange(height):
data_buffer = deepcopy(wdata) for x in xrange(width):
# if cell is active, increase its rating/value
if wdata[x][y][0] > 0:
# change the state of the cell
data_buffer[x][y][0] += 16
for y in xrange(height): # assign stat to red colour
for x in xrange(width): data_buffer[x][y][1] = data_buffer[x][y][0]
# if cell is active, increase its rating/value
if wdata[x][y][0] > 0:
# change the state of the cell
data_buffer[x][y][0] += 10
# assign stat to red colour # check we don't go too high
data_buffer[x][y][1] = data_buffer[x][y][0] # if the state is over 127, reset red
if data_buffer[x][y][0] > 127:
# assign max stat to red colour
data_buffer[x][y][1] = 0
# assign stat to green colour
data_buffer[x][y][2] = data_buffer[x][y][0] - 128
# check we don't go too high # if the state is over 128*2, reset green
if data_buffer[x][y][0] > 127: if data_buffer[x][y][0] > 255:
data_buffer[x][y][1] = 127 # assign max stat to green colour
# assign stat to green colour data_buffer[x][y][2] = 0
data_buffer[x][y][2] = data_buffer[x][y][0] - 127 # assign stat to blue colour
data_buffer[x][y][3] = data_buffer[x][y][0] - 255
if data_buffer[x][y][0] > 255: # if the state is over 128*3, reset blue
data_buffer[x][y][2] = 127 if data_buffer[x][y][0] > 383:
# assign stat to blue colour data_buffer[x][y][3] = data_buffer[x][y][0]%128
data_buffer[x][y][3] = data_buffer[x][y][0] - 255
if data_buffer[x][y][0] > 383: # if not active, check if adjacent cell is active
data_buffer[x][y][3] = 127 if wdata[x][y][0] == 0 and has_active_neighb(x, y):
# activate and colour
set_sdata(0,0,0) data_buffer[x][y][0] = 1
# E data_buffer[x][y][1] = 1
sdata[0][0] = [0,255,0,0,1] data_buffer[x][y][2] = 0
sdata[0][3] = [0,255,0,0,1] data_buffer[x][y][3] = 0
sdata[0][4] = [0,255,0,0,1]
sdata[0][5] = [0,255,0,0,1]
sdata[0][6] = [0,255,0,0,1]
# N
sdata[1][2] = [0,255,0,0,1]
sdata[1][4] = [0,255,0,0,1]
sdata[1][5] = [0,255,0,0,1]
sdata[1][6] = [0,255,0,0,1]
# D
sdata[2][1] = [0,255,0,0,1]
sdata[2][2] = [0,255,0,0,1]
sdata[2][3] = [0,255,0,0,1]
sdata[2][4] = [0,255,0,0,1]
sdata[2][6] = [0,255,0,0,1]
send_update()
exit()
# if not active, check if adjacent cell is active # set wdata to new buffer
if wdata[x][y][0] == 0 and has_active_neighb(x, y): wdata = data_buffer
# activate and colour
data_buffer[x][y][0] = 1
data_buffer[x][y][1] = 1
data_buffer[x][y][2] = 0
data_buffer[x][y][3] = 0
# wait to paint process next frame
time.sleep(sleeptime/1000.0)
# set wdata to new buffer # end of iteration, restart
wdata = data_buffer
# wait to paint process next frame # end of main animation loop
time.sleep(sleeptime/1000.0)
# close socket # close socket
UDPSock.close() UDPSock.close()

View File

@ -27,8 +27,6 @@ UDPSock.bind((outgoing_if, local_port))
# goes down or refuses connection # goes down or refuses connection
#UDPSock.connect((remote_host, remote_port)) #UDPSock.connect((remote_host, remote_port))
segmentsfile = open('segments','r')
hash = "s2l\n<8<18 " # 10 bytes hash = "s2l\n<8<18 " # 10 bytes
alpha = chr(255) alpha = chr(255)

99
clients/s2llib.py Normal file
View File

@ -0,0 +1,99 @@
# s2llib.py
# Python utility functions for syndelights
from socket import *
import sys, time
#from copy import deepcopy
class syndelights_canvas:
"""Holds the state of the canvas to be sent"""
segments_in_window = 8
def __init__(self, hpc, zb, w, h, seg_wins, hs, hsp, ts, tsp, deblvl):
# get hash passcode and z-buffer depth
self.hash_passcode = hpc
self.zed_buffer = zb
# main window dimensions
self.width = w
self.height = h
# number of windows with segment displays
self.segmented_windows_num = seg_wins
# set servers and ports
self.host_server = hs
self.host_server_port = hsp
self.target_server = ts
self.target_server_port = tsp
# debugging
self.debug_level = deblvl
# make data structures for windows and segments
self.reset_windows(0,127,127,127, 255)
self.reset_segment_windows(0, 127, 127, 127, 255)
def reset_windows(self, state, red, green, blue, alpha):
self.window_data = []
for y in xrange(self.height):
self.window_data.append([0] * self.width)
for x in xrange(self.width):
self.window_data[y][x] = dict(s=state, r=red, g=green, b=blue, a=alpha)
def reset_segment_windows(self, state, red, green, blue, alpha):
self.segmented_windows = []
for w in xrange(self.segmented_windows_num):
self.segmented_windows.append([0] * self.segments_in_window)
for s in xrange(self.segments_in_window):
self.segmented_windows[w][s] = dict(s=state, r=red, g=green, b=blue, a=alpha)
# convert [r, g, b, a] into a 4 character string
def int2chr(self, rgba_dict):
return chr(int(rgba_dict["r"])) + chr(int(rgba_dict["g"])) + chr(int(rgba_dict["b"])) + chr(int(rgba_dict["a"]))
# draw the data object, send it to the target server
def draw(self):
# prep header with hash, z-buffer and new line (12 bytes)
data = self.hash_passcode + chr(self.zed_buffer) + "\n"
# package window data
for y in xrange(self.height):
for x in xrange(self.width):
data = data + self.int2chr( self.window_data[y][x] )
data = data + "\n"
# package segment data
for w in xrange(self.segmented_windows_num):
for s in xrange(self.segments_in_window):
data = data + self.int2chr( self.segmented_windows[w][s] )
data = data + "\n"
if self.debug_level > 2:
print data
# send the data through UDP to remote server
self.UDPSock.sendto(data, (self.target_server, self.target_server_port))
def setwin_xy_srgba_array(self, x, y, srgba):
self.window_data[y][x] = dict(s=srgba[0], r=srgba[1], g=srgba[2], b=srgba[3], a=srgba[4])
def setwin_xy_sval(self, x, y, col, val):
if col == 's':
self.window_data[y][x]['s'] = val
if col == 'r':
self.window_data[y][x]['r'] = val
if col == 'g':
self.window_data[y][x]['r'] = val
if col == 'b':
self.window_data[y][x]['r'] = val
if col == 'a':
self.window_data[y][x]['r'] = val
def connect(self):
self.UDPSock = socket(AF_INET, SOCK_DGRAM)
self.UDPSock.bind((self.host_server, self.host_server_port))
def disconnect(self):
self.UDPSock.close()

22
clients/test.py Normal file
View File

@ -0,0 +1,22 @@
from s2llib import *
import time
width = 12
height = 8
test = syndelights_canvas("s2l\n<8<18 ", 1, width, height, width, "127.0.0.1", 5001, "127.0.0.1", 4422, 3)
test = syndelights_canvas("s2l\n<8<18 ", 1, width, height, width, "127.0.0.1", 5001, "127.0.0.1", 4321, 3)
test.connect()
test.reset_windows(0, 0, 0, 0, 127)
test.reset_segment_windows(0, 62, 62, 62, 63)
for y in xrange(height):
for x in xrange(width):
test.setwin_xy_srgba_array(x, y, [0, 255, 0, 0, 127])
test.draw()
time.sleep(0.5)
test.setwin_xy_srgba_array(x, y, [0, 0, 0, 0, 127])
test.disconnect()

View File

@ -173,7 +173,7 @@ void Server::listen()
void Server::send() void Server::send()
{ {
const int length = 12 + HEIGHT*(WIDTH*CHANNELS+1) + SEGWIDTH*(SEGNUM*SEGCHANNELS+1); const int length = HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) + SEGWIDTH*(SEGNUM*SEGCHANNELS+1);
static char data[length]; static char data[length];
while(1) while(1)
@ -188,10 +188,10 @@ void Server::send()
{ {
for(int k = 0; k < CHANNELS; k++) for(int k = 0; k < CHANNELS; k++)
{ {
data[i*(WIDTH*CHANNELS+1) + j*CHANNELS + k] = frame.windows[i][j][k]; data[HEADEROFFSET + i*(WIDTH*CHANNELS+1) + j*CHANNELS + k] = frame.windows[i][j][k];
} }
} }
data[i*(WIDTH*CHANNELS+1) + (WIDTH*CHANNELS)] = '\n'; data[HEADEROFFSET + i*(WIDTH*CHANNELS+1) + (WIDTH*CHANNELS)] = '\n';
} }
for(int i = 0; i < SEGWIDTH; i++) for(int i = 0; i < SEGWIDTH; i++)
@ -200,11 +200,11 @@ void Server::send()
{ {
for(int k = 0; k < SEGCHANNELS; k++) for(int k = 0; k < SEGCHANNELS; k++)
{ {
data[HEIGHT*(WIDTH*CHANNELS+1) + data[HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) +
i*(SEGNUM*SEGCHANNELS+1) + j*SEGCHANNELS + k] = frame.segments[i][j][k]; i*(SEGNUM*SEGCHANNELS+1) + j*SEGCHANNELS + k] = frame.segments[i][j][k];
} }
} }
data[HEIGHT*(WIDTH*CHANNELS+1) + data[HEADEROFFSET + HEIGHT*(WIDTH*CHANNELS+1) +
i*(SEGNUM*SEGCHANNELS+1) + (SEGNUM*SEGCHANNELS)] = '\n'; i*(SEGNUM*SEGCHANNELS+1) + (SEGNUM*SEGCHANNELS)] = '\n';
} }
} }