Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
shrapnel
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
shrapnel
Commits
f9f55b39
Commit
f9f55b39
authored
Jul 08, 2012
by
Sam Rushing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
separate quadtrees for background, viewports, moving objects
use cython quadtree implementation
parent
f50c1993
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
117 additions
and
30 deletions
+117
-30
coro/http/demo/websocket/field/field.py
coro/http/demo/websocket/field/field.py
+117
-30
No files found.
coro/http/demo/websocket/field/field.py
View file @
f9f55b39
# -*- Mode: Python -*-
from
coro.http.websocket
import
handler
,
websocket
import
math
import
pickle
import
random
import
re
import
region
import
quadtree
import
coro
W
=
coro
.
write_stderr
# need a way to declare a dirty region, and send a single
# redraw command for all the dirtied objects. So we need to separate
# object movement from redrawing... probably with a timer of some kind,
# accumulate dirty rects, then redraw in one swell foop
# another thing to consider: sending deltas rather than the entire list.
# for example, if the viewport hasn't moved, then the list of rectangles
# won't be changing. Can we send a diff? [this might just be easier with layers]
# for layers see: http://stackoverflow.com/questions/3008635/html5-canvas-element-multiple-layers
colors
=
[
'red'
,
'green'
,
'blue'
,
'magenta'
,
'purple'
,
'plum'
,
'orange'
]
# sample 'box' object.
class
box
:
def
__init__
(
self
,
color
,
rect
):
class
box
(
quadtree
.
ob
)
:
def
__init__
(
self
,
color
,
(
l
,
t
,
r
,
b
)
):
self
.
color
=
color
self
.
rect
=
rect
self
.
set_rect
(
l
,
t
,
r
,
b
)
def
move
(
self
,
dx
,
dy
):
x0
,
y0
,
x1
,
y1
=
self
.
get_rect
()
self
.
set_rect
(
int
(
x0
+
dx
),
int
(
y0
+
dy
),
int
(
x1
+
dx
),
int
(
y0
+
dy
)
)
def
cmd
(
self
,
xoff
,
yoff
):
# command to draw me relative to <xoff,yoff>?
x0
,
y0
,
x1
,
y1
=
self
.
get_rect
()
return
'B,%s,%d,%d,%d,%d'
%
(
self
.
color
,
x0
-
xoff
,
y0
-
yoff
,
x1
-
x0
,
y1
-
y0
)
def
__repr__
(
self
):
return
'<box (%d,%d,%d,%d)>'
%
self
.
get_rect
()
class
circle
(
box
):
def
__init__
(
self
,
color
,
center
,
radius
):
x
,
y
=
center
r
=
radius
self
.
color
=
color
self
.
center
=
center
self
.
radius
=
radius
self
.
set_rect
(
*
self
.
get_rect
())
def
get_rect
(
self
):
return
self
.
rect
x
,
y
=
self
.
center
r
=
self
.
radius
return
x
-
r
,
y
-
r
,
x
+
r
,
y
+
r
def
move
(
self
,
dx
,
dy
):
x
,
y
=
self
.
center
self
.
center
=
int
(
x
+
dx
),
int
(
y
+
dy
)
self
.
set_rect
(
*
self
.
get_rect
())
def
cmd
(
self
,
xoff
,
yoff
):
# command to draw me relative to <xoff,yoff>?
x
,
y
=
self
.
center
return
'C,%s,%d,%d,%d'
%
(
self
.
color
,
x
-
xoff
,
y
-
yoff
,
self
.
radius
)
def
__repr__
(
self
):
return
'<box (%d,%d,%d,%d)>'
%
self
.
rect
return
'<circle (%d,%d) radius=%d)>'
%
(
self
.
center
[
0
],
self
.
center
[
1
],
self
.
radius
)
# should have multiple qt's:
# 1) for the background, immutable
# 2) for the client viewports
# 3) for moving objects
class
field
:
def
__init__
(
self
,
w
=
1024
*
20
,
h
=
1024
*
20
):
self
.
w
=
w
self
.
h
=
h
self
.
clients
=
set
()
self
.
Q
=
quadtree
.
quadtree
()
self
.
Q_views
=
quadtree
.
quadtree
()
self
.
Q_back
=
quadtree
.
quadtree
()
self
.
Q_obs
=
quadtree
.
quadtree
()
self
.
generate_random_field
()
def
generate_random_field
(
self
):
for
i
in
range
(
5000
):
c
=
random
.
choice
(
colors
)
x
=
random
.
randint
(
0
,
self
.
w
-
100
)
y
=
random
.
randint
(
0
,
self
.
h
-
100
)
w
=
random
.
randint
(
50
,
300
)
h
=
random
.
randint
(
50
,
300
)
c
=
random
.
choice
(
colors
)
b
=
box
(
c
,
(
x
,
y
,
x
+
w
,
y
+
h
))
self
.
Q
.
insert
(
b
)
self
.
Q_back
.
insert
(
b
)
for
i
in
range
(
1000
):
coro
.
spawn
(
self
.
wanderer
)
def
new_conn
(
self
,
*
args
,
**
kwargs
):
c
=
field_conn
(
self
,
*
args
,
**
kwargs
)
self
.
clients
.
add
(
c
)
self
.
Q_views
.
insert
(
c
)
def
new_ob
(
self
,
ob
):
self
.
Q_obs
.
insert
(
ob
)
#W ('new ob %r\n' % (self.Q_obs,))
#self.Q_obs.dump()
def
move_ob
(
self
,
ob
,
dx
,
dy
):
r0
=
ob
.
get_rect
()
self
.
Q_obs
.
delete
(
ob
)
ob
.
move
(
dx
,
dy
)
r1
=
ob
.
get_rect
()
self
.
Q_obs
.
insert
(
ob
)
#self.Q_obs.dump()
# notify any viewers
r2
=
region
.
union
(
r0
,
r1
)
for
client
in
self
.
Q_views
.
search
(
r2
):
client
.
draw_window
()
class
field_conn
(
websocket
):
sleep
=
0.1
def
wanderer
(
self
):
# spawn me!
x
=
random
.
randint
(
100
,
self
.
w
-
100
)
y
=
random
.
randint
(
100
,
self
.
h
-
100
)
c
=
random
.
choice
(
colors
)
ob
=
circle
(
c
,
(
x
,
y
),
25
)
self
.
new_ob
(
ob
)
while
1
:
# pick a random direction
heading
=
random
.
randint
(
0
,
360
)
*
(
math
.
pi
/
180.0
)
speed
=
(
random
.
random
()
*
10
)
+
3
dx
=
math
.
cos
(
heading
)
*
speed
dy
=
math
.
sin
(
heading
)
*
speed
# go that way for 20 steps
for
i
in
range
(
20
):
self
.
move_ob
(
ob
,
dx
,
dy
)
# not working yet...
## if not ob.range_check (0, 0, self.w, self.h):
## W ('%r hit an edge!\n' % (ob,))
## dx = - (dx * 5)
## dy = - (dy * 5)
## self.move_ob (ob, dx, dy)
coro
.
sleep_relative
(
self
.
sleep
)
class
field_conn
(
websocket
,
quadtree
.
ob
):
def
__init__
(
self
,
field
,
*
args
,
**
kwargs
):
websocket
.
__init__
(
self
,
*
args
,
**
kwargs
)
...
...
@@ -52,12 +144,13 @@ class field_conn (websocket):
self
.
field
=
field
rx
=
random
.
randint
(
0
,
self
.
field
.
w
-
1024
)
ry
=
random
.
randint
(
0
,
self
.
field
.
h
-
1024
)
self
.
rect
=
(
rx
,
ry
,
rx
+
1024
,
ry
+
1024
)
self
.
set_rect
(
rx
,
ry
,
rx
+
1024
,
ry
+
1024
)
self
.
draw_window
()
self
.
mouse_down
=
None
,
None
def
move_window
(
self
,
mx
,
my
):
x0
,
y0
,
x1
,
y1
=
self
.
rect
self
.
field
.
Q_views
.
delete
(
self
)
x0
,
y0
,
x1
,
y1
=
self
.
get_rect
()
x0
=
x0
+
mx
;
y0
=
y0
+
my
x1
=
x1
+
mx
;
y1
=
y1
+
my
if
x0
<
0
:
...
...
@@ -68,17 +161,20 @@ class field_conn (websocket):
x1
=
self
.
field
.
w
-
1024
;
x0
=
x1
-
1024
if
y1
>
self
.
field
.
h
-
1024
:
y1
=
self
.
field
.
h
-
1024
;
y0
=
y1
-
1024
self
.
rect
=
(
x0
,
y0
,
x1
,
y1
)
self
.
set_rect
(
x0
,
y0
,
x1
,
y1
)
self
.
field
.
Q_views
.
insert
(
self
)
self
.
draw_window
()
self
.
send_text
(
'M pos=%d,%d'
%
self
.
rect
[:
2
])
self
.
send_text
(
'M pos=%d,%d'
%
self
.
get_rect
()[:
2
])
def
draw_qt
(
self
,
r
,
Q
):
px
,
py
=
self
.
get_rect
()[:
2
]
for
ob
in
Q
.
search
(
self
.
rect
):
r
.
append
(
ob
.
cmd
(
px
,
py
))
def
draw_window
(
self
):
r
=
[
'F'
]
px
,
py
=
self
.
rect
[:
2
]
for
ob
in
self
.
field
.
Q
.
search_gen
(
self
.
rect
):
c
=
ob
.
color
x0
,
y0
,
x1
,
y1
=
ob
.
get_rect
()
r
.
append
(
'B,%s,%d,%d,%d,%d'
%
(
c
,
x0
-
px
,
y0
-
py
,
x1
-
x0
,
y1
-
y0
))
self
.
draw_qt
(
r
,
self
.
field
.
Q_back
)
self
.
draw_qt
(
r
,
self
.
field
.
Q_obs
)
self
.
send_text
(
'|'
.
join
(
r
))
def
send_text
(
self
,
payload
):
...
...
@@ -100,7 +196,7 @@ class field_conn (websocket):
elif
ascii
==
68
:
# D
self
.
move_window
(
10
,
0
)
elif
ascii
==
82
:
# R
x0
,
y0
=
self
.
rect
[:
2
]
x0
,
y0
=
self
.
get_rect
()
[:
2
]
self
.
move_window
(
-
x0
,
-
y0
)
elif
event
[
0
]
==
'MD'
:
self
.
on_mouse_down
(
int
(
event
[
1
]),
int
(
event
[
2
]))
...
...
@@ -135,15 +231,6 @@ class field_conn (websocket):
def
on_mouse_up
(
self
,
x1
,
y1
):
x0
,
y0
=
self
.
mouse_down
self
.
mouse_down
=
None
,
None
# 1) draw a box in the region chosen
#if x0 > x1:
# x0, x1 = x1, x0
#if y0 > y1:
# y0, y1 = y1, y0
#px, py = self.rect[:2]
#b = box (random.choice (colors), (x0+px, y0+py, x1+px, y1+py))
#self.field.Q.insert (b)
# 2) or move the window
if
x0
is
not
None
:
self
.
move_window
(
x0
-
x1
,
y0
-
y1
)
self
.
draw_window
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment