[pypy-svn] r29338 - in pypy/dist/pypy/translator: js js/demo/jsdemo js/demo/jsdemo/templates js/tools oosupport

fijal at codespeak.net fijal at codespeak.net
Mon Jun 26 09:44:27 CEST 2006


Author: fijal
Date: Mon Jun 26 09:44:24 2006
New Revision: 29338

Modified:
   pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
   pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid
   pypy/dist/pypy/translator/js/jsbuiltin.py
   pypy/dist/pypy/translator/js/metavm.py
   pypy/dist/pypy/translator/js/tools/start_bnb.py
   pypy/dist/pypy/translator/oosupport/metavm.py
Log:
Added date() builtin. Added sprite management which leads to a little bit smoother animation.


Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py	(original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py	Mon Jun 26 09:44:24 2006
@@ -7,11 +7,11 @@
 from pypy.translator.js.demo.jsdemo.controllers import Root
 from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
 
-from pypy.translator.js.proxy.testme.servermessage import log, ServerMessage, PMSG_INLINE_FRAME
+from pypy.translator.js.proxy.testme.servermessage import log, ServerMessage, PMSG_INLINE_FRAME, PMSG_DEF_ICON
 from pypy.translator.js.proxy.testme.msgstruct import *
 from cherrypy import session
 
-import re, time, sys, os, urllib, socket
+import re, time, sys, os, urllib, socket, copy
 
 class SortY(object):
     def __init__(self, data):
@@ -20,6 +20,55 @@
     def __cmp__(self, other):
         return cmp(self.data['y'], other.data['y'])
 
+
+class SpriteManager(object):
+    def __init__(self):
+        self.sprite_sets = {}
+        self.positions = {}
+        self.num = 0
+        self.next_pos = {}
+        self.last_seen = set()
+        self.seen = set()
+    
+    def def_icon(self, icon_code):
+        self.sprite_sets[icon_code] = []
+    
+    def get_sprite(self, icon_code, x, y):
+        try:
+            to_ret = self.positions[(icon_code, x, y)]
+            del self.positions[(icon_code, x, y)]
+            self.next_pos[(icon_code, x, y)] = to_ret
+            self.seen.add((icon_code, to_ret))
+            return "still", to_ret
+        except KeyError:
+            try:
+                try:
+                    to_ret = self.sprite_sets[icon_code].pop()
+                except KeyError:
+                    self.def_icon(icon_code)
+                    raise IndexError
+                self.next_pos[(icon_code, x, y)] = to_ret
+                self.seen.add((icon_code, to_ret))
+                return "move", to_ret
+            except IndexError:
+                next = self.num
+                self.num += 1
+                self.next_pos[(icon_code, x, y)] = next
+                self.seen.add((icon_code, next))
+                return "new", next
+    
+    def end_frame(self):
+        self.positions = copy.deepcopy(self.next_pos)
+        self.next_pos = {}
+        to_ret = []
+        #import pdb;pdb.set_trace()
+        for ic, i in self.last_seen - self.seen:
+            self.sprite_sets[ic].append(i)
+            to_ret.append(i)
+        self.last_seen = self.seen
+        self.seen = set()
+        return to_ret
+
 # Needed double inheritance for both server job
 # and semi-transparent communication proxy
 class BnbRoot(Root, BasicExternal):
@@ -40,6 +89,8 @@
         'get_message' : MethodDesc( [('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]})
     }
     
+    sm = SpriteManager()
+    
     def serverMessage(self):
         sessionid = session['_id']
         if sessionid not in self._serverMessage:
@@ -49,7 +100,7 @@
     @turbogears.expose(html="jsdemo.templates.bnb")
     def index(self):
         import time
-        self.last_frames = set()
+        self.new_sprites = 0
         return dict(now=time.ctime(), onload=self.jsname, code=self.jssource)
     
     def sessionSocket(self, close=False):
@@ -72,8 +123,13 @@
     def get_message(self):
         #XXX hangs if not first sending CMSG_PING!
         sm   = self.serverMessage()
-        size = 10000 #XXX should really loop until all data is handled
-        data = sm.data + self.sessionSocket().recv(size)
+        data = sm.data
+        sock = self.sessionSocket()
+        while True:
+            try:
+                data += sock.recv(4096, socket.MSG_DONTWAIT)
+            except:    
+                break
         while sm.n_header_lines > 0 and '\n' in data:
             sm.n_header_lines -= 1
             header_line, data = data.split('\n',1)
@@ -104,22 +160,23 @@
         #    log('MESSAGES:lenbefore=%d, inline_frames=%s, lenafter=%d' % (
         #        len_before, inline_frames, len(messages)))
         to_append = []
-        next_last = set()
-        keep_sprites = []
         for i, msg in enumerate(messages):
             if msg['type'] == PMSG_INLINE_FRAME:
                 for next in msg['sprites']:
-#                    if not next in self.last_frames:
-                        # sort them by y axis
-                    to_append.append(SortY({'type':'sprite', 'x':str(next[1]), 'y':str(next[2]), 'icon_code':str(next[0])}))
-                    #next_last.add(next)
+                    new_sprite, s_num = self.sm.get_sprite(*next)
+                    if new_sprite == 'new':
+                        #if self.new_sprites < 100:
+                        to_append.append({'type':'ns', 's':s_num, 'icon_code':str(next[0]), 'x':str(next[1]), 'y':str(next[2])})
+                        self.new_sprites += 1
+                    elif new_sprite == 'move':
+                        to_append.append({'type':'sm', 's':str(s_num), 'x':str(next[1]), 'y':str(next[2])})
                 del messages[i]
-        
-        self.last_frames = next_last
-        to_append.sort()
-        messages += [i.data for i in to_append]
-        
-        messages.append({'type':'end_frame'})
+
+        for i in self.sm.end_frame():
+            to_append.append({'type':'ds', 's':str(i)})
+        messages += to_append
+        #messages.append(to_append[0])
+        #print len(messages)
         return dict(messages=messages)
 
 BnbRootInstance = BnbRoot()

Modified: pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid	(original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/templates/bnb.kid	Mon Jun 26 09:44:24 2006
@@ -3,6 +3,7 @@
 <head>
     <meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
     <title>Bub'n'bros</title>
+    <script language="javascript" src="/tgtest${std.tg_js}/MochiKit.js"/>
     <script language="javascript" src="${std.tg_js}/MochiKit.js"/>
     <script type="text/javascript" src="js_basic.js"/>
     <script type="text/javascript">

Modified: pypy/dist/pypy/translator/js/jsbuiltin.py
==============================================================================
--- pypy/dist/pypy/translator/js/jsbuiltin.py	(original)
+++ pypy/dist/pypy/translator/js/jsbuiltin.py	Mon Jun 26 09:44:24 2006
@@ -3,7 +3,8 @@
 
 from pypy.translator.oosupport.metavm import InstructionList, PushAllArgs
 from pypy.translator.js.metavm import SetBuiltinField, ListGetitem, ListSetitem, \
-    GetBuiltinField, CallBuiltin, Call, SetTimeout, XmlSetCallback, ListContains
+    GetBuiltinField, CallBuiltin, Call, SetTimeout, XmlSetCallback, ListContains,\
+    NewBuiltin
 
 from pypy.rpython.ootypesystem import ootype
 
@@ -23,6 +24,7 @@
             'll_int' : CallBuiltin('parseInt'),
             'alert' : CallBuiltin('alert'),
             'seval' : CallBuiltin('seval'),
+            'date': NewBuiltin('Date')
         }
         self.builtin_obj_map = {
             ootype.String.__class__: {

Modified: pypy/dist/pypy/translator/js/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/js/metavm.py	(original)
+++ pypy/dist/pypy/translator/js/metavm.py	Mon Jun 26 09:44:24 2006
@@ -10,6 +10,13 @@
 from types import FunctionType
 from pypy.objspace.flow.model import Constant
 
+class NewBuiltin(MicroInstruction):
+    def __init__(self, arg):
+        self.arg = arg
+    
+    def render(self, generator, op):
+        generator.ilasm.new(self.arg)
+
 class _ListSetitem(MicroInstruction):
     def render(self, generator, op):
         generator.load(op.args[1])

Modified: pypy/dist/pypy/translator/js/tools/start_bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/tools/start_bnb.py	(original)
+++ pypy/dist/pypy/translator/js/tools/start_bnb.py	Mon Jun 26 09:44:24 2006
@@ -16,6 +16,7 @@
 from pypy.translator.js.modules.xmlhttp import XMLHttpRequest
 from pypy.translator.js.modules.mochikit import logDebug, createLoggingPane
 from pypy.translator.js.modules.dom import get_document
+from pypy.translator.js.modules.bltns import date
 
 import time
 import os
@@ -49,7 +50,17 @@
         self.n_received_inline_frames = 0
         self.n_rendered_inline_frames = 0
         self.n_rendered_dynamic_sprites = 0
+        self.fps = 0
+        self.starttime = 0.0
         self.n_sprites = 0 #why is inline frame broken up?
+    
+    def register_frame(self):
+        self.n_rendered_inline_frames += 1
+        if self.n_rendered_inline_frames > 10:
+            next_time = date()
+            self.fps = 10000/(next_time - self.starttime)
+            self.n_rendered_inline_frames = 0
+            self.starttime = next_time
 
 stats = Stats()
 
@@ -82,6 +93,7 @@
             img.setAttribute("style", 'position:absolute; left:0px; top:0px; visibility:visible')
             self.sprite_queues[icon_code].append(img)
             get_document().getElementById("playfield").appendChild(img)
+            stats.n_sprites += 1
             return img
     
     def revive(self):
@@ -91,7 +103,44 @@
             self.sprite_queues[i] = self.sprite_queues[i] + self.used[i]
             self.used[i] = []
         
-sc = SpriteContainer();
+#sc = SpriteContainer();
+
+class SpriteManager(object):
+    def __init__(self):
+        self.sprites = {}
+        self.filenames = {}
+
+    def add_icon(self, icon_code, filename):
+        self.filenames[icon_code] = filename
+        #self.sprite_queues[icon_code] = []
+        #self.used[icon_code] = []
+        # FIXME: Need to write down DictIterator once...
+        #self.icon_codes.append(icon_code)
+
+    def add_sprite(self, s, icon_code, x, y):
+        #try:
+        #    img = self.sprite_queues[icon_code].pop()
+        #except IndexError:
+        stats.n_sprites += 1
+        img = get_document().createElement("img")
+        img.setAttribute("src", self.filenames[icon_code])
+        img.setAttribute("style", 'position:absolute; left:'+x+'px; top:'+y+'px; visibility:visible')
+        get_document().getElementById("playfield").appendChild(img)
+        self.sprites[s] = img
+        return img
+
+    def move_sprite(self, s, x, y):
+        i = self.sprites[s]
+        i.style.top = y + 'px'
+        i.style.left = x + 'px'
+        i.style.visibility = 'visible'
+    
+    def hide_sprite(self, s):
+        i = self.sprites[s]
+        i.style.visibility = "hidden"
+        #pass
+
+sm = SpriteManager()
 
 def process_message(msg):
     if msg['type'] == 'def_playfield':
@@ -109,23 +158,21 @@
 ##        img.setAttribute("style", 'position:absolute; left:0; top:0')
 ##        img.setAttribute("id", msg["icon_code"])
 ##        get_document().getElementById("playfield").appendChild(img)
-        sc.add_icon(msg['icon_code'], msg['filename'])
-    elif msg['type'] == 'sprite':
-        #img = get_document().getElementById(msg["icon_code"])
-        #logDebug(str(img.left) + " " + str(img.right))
-        img = sc.get_sprite(msg['icon_code'])
-        img.style.left = msg['x'] + 'px'
-        img.style.top = msg['y'] + 'px'
-        stats.n_sprites += 1
-        get_document().title = str(stats.n_sprites) + " sprites"
-    elif msg['type'] == 'end_frame':
-        pass
-        sc.revive()
+        sm.add_icon(msg['icon_code'], msg['filename'])
+    elif msg['type'] == 'ns':
+        sm.add_sprite(msg['s'], msg['icon_code'], msg['x'], msg['y'])
+    elif msg['type'] == 'sm':
+        sm.move_sprite(msg['s'], msg['x'], msg['y'])
+    elif msg['type'] == 'ds':
+        sm.hide_sprite(msg['s'])
 
 def bnb_dispatcher(msgs):
     BnbRootInstance.get_message(bnb_dispatcher)
     for msg in msgs['messages']:
         process_message(msg)
+    stats.register_frame()
+    get_document().title = str(stats.n_sprites) + " sprites " + str(stats.fps)
+    #sc.revive()
     
 def run_bnb():
     def bnb():
@@ -134,7 +181,7 @@
         BnbRootInstance.get_message(bnb_dispatcher)
     
     from pypy.translator.js.demo.jsdemo.bnb import BnbRoot
-    fn = compile_function(bnb, [], root = BnbRoot, run_browser = False)
+    fn = compile_function(bnb, [], root = BnbRoot, run_browser = True)
     fn()
 
 if __name__ == '__main__':

Modified: pypy/dist/pypy/translator/oosupport/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/metavm.py	(original)
+++ pypy/dist/pypy/translator/oosupport/metavm.py	Mon Jun 26 09:44:24 2006
@@ -124,7 +124,7 @@
             try:
                 return self.builtins.builtin_map[func_name](generator, op)
             except KeyError:
-                pass
+                return self.class_map['CallBuiltin'](func_name)(generator, op)
         return self.class_map['Call'].render(generator, op)
     
 class _GetFieldDispatcher(_GeneralDispatcher):



More information about the Pypy-commit mailing list