Commits

Alberto Torres  committed ad9207d

Better tracebacks from sensors, moved parts of gameobject to new files, added a GameObject.visible property.

  • Participants
  • Parent commits bc2d941

Comments (0)

Files changed (7)

File CMakeLists.txt

 
 set(PYGAMEKIT_SRC
     actuator.pxi
+    animation.pxi
     blendfile.pxi
+    collision.pxi
     controller.pxi
     engine.pxi
     sensor.pxi

File animation.pxi

+
+cdef enum akAnimationEvalMode:
+    AK_ACT_LOOP
+    AK_ACT_END
+    AK_ACT_INVERSE
+
+# This wraps gkAnimationPlayer
+cdef class Animation(pywrap):
+    
+    cdef gkGameObject *ob
+    cdef public Real blend_time
+    cdef public int priority
+    
+    def play(self):
+        self.ob.playAnimation(
+            <gkAnimationPlayer*>self._p,
+            self.blend_time, AK_ACT_END, self.priority)
+        
+    def stop(self):
+        self.ob.stopAnimation(<gkAnimationPlayer*>self._p)
+        
+    property weight:
+        def __get__(self):
+            return (<gkAnimationPlayer*>self._p).getWeight()
+        def __set__(self,  v):
+            (<gkAnimationPlayer*>self._p).setWeight(v)
+            
+    property length:
+        def __get__(self):
+            return (<gkAnimationPlayer*>self._p).getLength()
+        #def __set__(self,  v):
+            #(<gkAnimationPlayer*>self._p).setLength(v)
+            
+    property speed_factor:
+        def __get__(self):
+            return (<gkAnimationPlayer*>self._p).getSpeedFactor()
+        def __set__(self, v):
+            (<gkAnimationPlayer*>self._p).setSpeedFactor(v)
+    
+
+cdef class AnimationList(pywrap):
+        
+    def aaa__dict__(self): # this should returna dict with all the animations, but it only returns the active one.
+        cdef int hack1 "h;/*" = 0
+        cdef gkAnimationsIterator it, hack2 "utHashTable<gkHashedString, gkAnimationPlayer*>::Iterator __pyx_v_it /**/"
+        hack2 = (<gkGameObject*>self._p).getAnimations().iterator()
+        
+        cdef Animation a
+        ret = {}
+        
+        while it.hasMoreElements():
+            a = Animation().P(it.peekNextValue())
+            a.ob = <gkGameObject*>self._p
+            ret[it.peekNextKey().str().c_str()] = a
+            it.next()
+        
+        return ret
+        
+    def __iter__(self):
+        return self.__dict__().__iter__() #TODO: can be made more efficient
+        
+    def __getitem__(self,item):
+        cdef Animation a
+        cdef gkAnimationPlayer *ap
+        ap = (<gkGameObject*>self._p).getAnimationPlayer(to_stdstring(item))
+        if ap==NULL:
+            ap = (<gkGameObject*>self._p).addAnimation(to_stdstring(item))
+            if ap==NULL:
+                return None
+        a = Animation().P(ap)
+        a.ob = <gkGameObject*>self._p
+        return a
+
+    def __len__(self):
+        return (<gkGameObject*>self._p).getAnimations().size()

File collision.pxi

+
+#TODO: function for getting the appropiate python object from a gkGameObject pointer, instead of elifs everywhere
+
+
+from gameobject cimport *
+
+cdef list collision_callbacks = []
+
+
+cdef class Collision(Sensor):
+    
+    cdef gkPhysicsController *pc
+    cdef std_string *prop
+    cdef gkGameObjectArray *objlist
+    
+    def __init__(self, _prop):
+        self.prop = new std_string(_prop) #is this freed?
+        self.init_sensor([])
+        
+    cdef void _set_owner(self, GameObject owner):
+        self.owner = owner
+        self.pc = (<gkGameObject*>self.owner._p).getPhysicsController()
+        self.objlist = new gkGameObjectArray()
+        self.callback_list = collision_callbacks
+        
+    def __nonzero__(self):
+        if self.pc!=NULL:
+            return self.pc.sensorCollides(self.prop[0], to_stdstring(""), False, False, self.objlist)
+            
+    property hit_objects:
+        
+        def __get__(self):
+            return GameObjectArray().P(self.objlist)
+            
+    def __str__(self):
+        if self: return "<Collision Active>"
+        else: return "<Collision>"
+        
+cdef void evaluate_collision_callbacks() except *:
+    cdef bool s
+    cdef Collision e
+    
+    for e in collision_callbacks:
+        if e.pc:
+            s = e.pc.sensorCollides(e.prop[0], to_stdstring(""), False, False, <gkGameObjectArray*>e.objlist)
+            if e.prevstate!=s:
+                e.execute()
+            e.prevstate = s
+            
+        
 include "controller.pxi"
 include "actuator.pxi"
 include "gameobject.pxi"
+include "animation.pxi"
+include "collision.pxi"
 include "scene.pxi"
 include "engine.pxi"
 include "blendfile.pxi"

File gameobject.pxd

 cdef extern from "OgreSceneNode.h":
     cdef cppclass Ogre_SceneNode "Ogre::SceneNode":
         const_std_string& getName()
-        
+        void setVisible(bool,bool)
         
         Ogre_MovableObject *getAttachedObject (int)
 
         
         Ogre_SceneNode*          getNode()
         int getType()
+        gkGameObjectProperties&   getProperties()
         
         gkScene*        getOwner()
         
         gkAnimationPlayer*     addAnimation(const_std_string name)
         gkAnimationPlayer*     getAnimationPlayer(const_std_string name)
         
-        void playAnimation(gkAnimationPlayer* act, Real blend)#, int mode = AK_ACT_END, int priority = 0)
+        void playAnimation(gkAnimationPlayer* act, Real blend, int mode, int priority)
         void stopAnimation(gkAnimationPlayer* act)
         
         gkAnimations& getAnimations()
     cdef cppclass gkEntity(gkGameObject):
         void setSkeleton(gkSkeleton* skel)
         void createInstance()
+        
+    enum gkGameObjectMode:
+        GK_GHOST
+        GK_ACTOR
+        GK_INVISIBLE
+        GK_OCCLUDER
+        GK_HAS_LOGIC
+        GK_IMMOVABLE
+        GK_STATIC_GEOM
+        
+    cdef cppclass gkGameObjectProperties:
+        int m_mode
+        bool isActor()
+        bool isInvisible()
+        bool isOccluder()
+        bool isGhost()
     
 cdef extern from "Animation/gkAnimation.h":
     cdef cppclass gkAnimation:

File gameobject.pxi

 
 #TODO: function for getting the appropiate python object from a gkGameObject pointer, instead of elifs everywhere
-#TODO: separate callbacks, physics
 
 from variable cimport *
 from gameobject cimport *
 
 OBJECT_TYPES = 'NULL', 'CAMERA', 'LIGHT', 'ENTITY', 'OBJECT', 'SKELETON', 'PARTICLES'
 
-cdef list collision_callbacks = []
 
 cdef gkGameObject* cloneRecursiveImpl(gkGameObject* ob, int lifespan=0, bool instance=True):
     
         old = getattr(sensor,'owner',None)
         if old is not None and old!=self:
             sensor = sensor.copy()
-        sensor.owner = self
-        sensor._init()
+        sensor._set_owner(self)
         return sensor
         
     def add_actuator(self, actuator):
         old = getattr(actuator,'owner',None)
         if old is not None and old!=self:
             actuator = actuator.copy()
-        actuator.owner = self
-        actuator._init()
+        actuator._set_owner(self)
         return actuator
         
     def __richcmp__(self, other, op):
                 return (<GameObject>other)._p != <void *>self._p
         return False
         
+    property visible:
+        def __get__(self):
+            return not (<gkGameObject*>self._p).getProperties().isInvisible()
+        
+        def __set__(self, bool v):
+            cdef gkGameObjectProperties *prop = &((<gkGameObject*>self._p).getProperties())
+            prop.m_mode |= GK_INVISIBLE
+            if v:
+                prop.m_mode -= GK_INVISIBLE
+            (<gkGameObject*>self._p).getNode().setVisible(v, False)
+        
 cdef class Entity(GameObject):
     
     def buildTangentVectors(self, sourceTexCoordSet):
     def __len__(self):
         return (<gkGameObjectArray*>self._p).size()
     
-# This wraps gkAnimationPlayer
-cdef class Animation(pywrap):
-    
-    cdef gkGameObject *ob
-    
-    def play(self, blend = 1.0):
-        self.ob.playAnimation(<gkAnimationPlayer*>self._p, blend)
-        
-    def stop(self, blend = 1.0):
-        self.ob.stopAnimation(<gkAnimationPlayer*>self._p)
-        
-    property weight:
-        def __get__(self):
-            return (<gkAnimationPlayer*>self._p).getWeight()
-        def __set__(self,  v):
-            (<gkAnimationPlayer*>self._p).setWeight(v)
-            
-    property length:
-        def __get__(self):
-            return (<gkAnimationPlayer*>self._p).getLength()
-        #def __set__(self,  v):
-            #(<gkAnimationPlayer*>self._p).setLength(v)
-            
-    property speed_factor:
-        def __get__(self):
-            return (<gkAnimationPlayer*>self._p).getSpeedFactor()
-        def __set__(self, v):
-            (<gkAnimationPlayer*>self._p).setSpeedFactor(v)
-    
-
-cdef class AnimationList(pywrap):
-        
-    def aaa__dict__(self): # this should returna dict with all the animations, but it only returns the active one.
-        cdef int hack1 "h;/*" = 0
-        cdef gkAnimationsIterator it, hack2 "utHashTable<gkHashedString, gkAnimationPlayer*>::Iterator __pyx_v_it /**/"
-        hack2 = (<gkGameObject*>self._p).getAnimations().iterator()
-        
-        cdef Animation a
-        ret = {}
-        
-        while it.hasMoreElements():
-            a = Animation().P(it.peekNextValue())
-            a.ob = <gkGameObject*>self._p
-            ret[it.peekNextKey().str().c_str()] = a
-            it.next()
-        
-        return ret
-        
-    def __iter__(self):
-        return self.__dict__().__iter__() #TODO: can be made more efficient
-        
-    def __getitem__(self,item):
-        cdef Animation a
-        cdef gkAnimationPlayer *ap
-        ap = (<gkGameObject*>self._p).getAnimationPlayer(to_stdstring(item))
-        if ap==NULL:
-            ap = (<gkGameObject*>self._p).addAnimation(to_stdstring(item))
-            if ap==NULL:
-                return None
-        a = Animation().P(ap)
-        a.ob = <gkGameObject*>self._p
-        return a
-
-    def __len__(self):
-        return (<gkGameObject*>self._p).getAnimations().size()
-        
-
-cdef class Collision(Sensor):
-    
-    cdef gkPhysicsController *pc
-    cdef std_string *prop
-    cdef gkGameObjectArray *objlist
-    
-    def __init__(self, _prop):
-        self.prop = new std_string(_prop) #is this freed?
-        self.init_sensor([])
-        
-    cdef void _init(self):
-        self.pc = (<gkGameObject*>self.owner._p).getPhysicsController()
-        self.objlist = new gkGameObjectArray()
-        self.callback_list = collision_callbacks
-        
-    def __nonzero__(self):
-        if self.pc!=NULL:
-            return self.pc.sensorCollides(self.prop[0], to_stdstring(""), False, False, self.objlist)
-            
-    property hit_objects:
-        
-        def __get__(self):
-            return GameObjectArray().P(self.objlist)
-            
-    def __str__(self):
-        if self: return "<Collision Active>"
-        else: return "<Collision>"
-        
-cdef void evaluate_collision_callbacks() except *:
-    cdef bool s
-    cdef Collision e
-    
-    for e in collision_callbacks:
-        if e.pc:
-            s = e.pc.sensorCollides(e.prop[0], to_stdstring(""), False, False, <gkGameObjectArray*>e.objlist)
-            if e.prevstate!=s:
-                e.execute()
-            e.prevstate = s
-            
-        
+     
     cdef readonly unsigned long int last_time
 
     cdef gkClock *timer
+    cdef str tb
+    cdef object stackdata
     
     def __init__(self):
         self.init_sensor([])
     def with_links_of(self, sensor):
         self.link(sensor.links)
         return self
-
-    cdef void _init(self):
-        pass
     
     cdef void _set_owner(self, GameObject obj):
         self.owner = obj
         self.timer = new gkClock()
         self.callback_list = callback_list
         self.links = []
-
+        self.tb = ""
+        self.stackdata = traceback.extract_stack()[-1]
+        
     cdef void execute(self) except *:
         if self.links:
             self.reset_time()
+            tb = ""
             for f in self.links:
-                f(self)
+                try:
+                    f(self)
+                except:
+                    exc_type, exc_value, exc_traceback = sys.exc_info()
+                    if self.stackdata is not None:
+                        sd = [self.stackdata]
+                    tbl = sd + [x for x in
+                          traceback.extract_tb(exc_traceback)
+                          if not x[0].endswith('.pxi')]
+                    tb += ''.join(traceback.format_list(tbl))
+                    tb += ''.join(traceback.format_exception_only(exc_type, exc_value))
+            if tb and tb!=self.tb:
+                print tb
+                self.tb = tb
         else:
             self.callback_list.pop(self.callback_list.index(self))