Merge: serialization: safe formal types, fix warnings in generated code and more
authorJean Privat <jean@pryen.org>
Wed, 2 Aug 2017 18:17:06 +0000 (14:17 -0400)
committerJean Privat <jean@pryen.org>
Wed, 2 Aug 2017 18:17:06 +0000 (14:17 -0400)
* Use `GetName` to better restrict the accepted static type for attributes with formal types. This should complete the protection against the injection of unexpected types through deserialization (reported by @ppepos).
* Update `nitserial` to intrude import modules with private serializable classes, instead of skipping them. Serializing private classes from the lib should probably be avoided, but at least now we support them and we can see them.
* Fix the deserialization of maps from JSON with metadata and cycles. A difference in the deserialization order could cause a reference to be read before the referenced object. This issue may still be caused by versionning, so a foolproof solution should probably be added to the JSON deserializer.
* Fix a warning in generated code, it was generated for each `serialize` class (quite a lot). It caused 25 warnings just in lib/github/api.nit.
* Implement serialization for the private classes of `core::queue` and don't crash on deserialization errors in `a_star`.

Pull-Request: #2531
Reviewed-by: Jean Privat <jean@pryen.org>

contrib/asteronits/src/asteronits.nit
lib/a_star.nit
lib/gamnit/camera_control_linux.nit
lib/gamnit/cameras.nit
lib/gamnit/flat/flat_core.nit
lib/gamnit/gamnit_linux.nit

index 1c148db..d7621de 100644 (file)
@@ -89,6 +89,8 @@ redef class App
 
        redef fun accept_event(event)
        do
+               if super then return true
+
                if event isa QuitEvent then
                        exit 0
                else if event isa KeyEvent then
index de909db..9ea68e8 100644 (file)
@@ -90,7 +90,7 @@ class Node
        # lifetime limited to evocation of `path_to`
        private var open: Bool = false
 
-       # Main functionnality, returns path from `self` to `dest`
+       # Main functionality, returns path from `self` to `dest`
        fun path_to(dest: N, max_cost: Int, context: PathContext): nullable AStarPath[N]
        do
                return path_to_alts(dest, max_cost, context, null)
index 8c92e91..2aa5d48 100644 (file)
@@ -23,7 +23,7 @@ redef class EulerCamera
        # Zoom factor, default at 1.2, higher means more reactive zoom effect
        var camera_zoom_mod = 1.2 is writable
 
-       # Scoll trigger button mask from SDL2 (1: left, 2: middle, 4: right)
+       # Scroll trigger button mask from SDL2 (1: left, 2: middle, 4: right)
        #
        # Set to 0 to deactivate the scrolling feature.
        var camera_pan_mask = 2 is writable
index 688082b..c83ace3 100644 (file)
@@ -225,14 +225,14 @@ class UICamera
        end
 
        # Convert the position `x, y` on screen, to UI coordinates
-       fun camera_to_ui(x, y: Numeric): Point[Float]
+       fun camera_to_ui(x, y: Numeric): Point3d[Float]
        do
                # FIXME this kind of method should use something like a canvas
                # instead of being hard coded on the display.
 
                var wx = x.to_f * width / display.width.to_f - position.x
                var wy = y.to_f * height / display.height.to_f - position.y
-               return new Point[Float](wx, -wy)
+               return new Point3d[Float](wx, -wy, 0.0)
        end
 
        # Center of the screen, from the point of view of the camera, at z = 0
index c8ffed4..dcb11f6 100644 (file)
@@ -378,10 +378,10 @@ redef class App
        var ui_camera = new UICamera(app.display.as(not null)) is lazy
 
        # World sprites drawn as seen by `world_camera`
-       var sprites: Set[Sprite] = new SpriteSet
+       var sprites = new SpriteSet
 
        # UI sprites drawn as seen by `ui_camera`, over world `sprites`
-       var ui_sprites: Set[Sprite] = new SpriteSet
+       var ui_sprites = new SpriteSet
 
        # Main method to refine in clients to update game logic and `sprites`
        fun update(dt: Float) do end
@@ -537,7 +537,7 @@ redef class App
        # Draw world sprites from `sprites`
        protected fun frame_core_world_sprites(display: GamnitDisplay)
        do
-               frame_core_sprites(display, sprites.as(SpriteSet), world_camera)
+               frame_core_sprites(display, sprites, world_camera)
        end
 
        # Draw UI sprites from `ui_sprites`
@@ -546,7 +546,7 @@ redef class App
                # Reset only the depth buffer
                glClear gl_DEPTH_BUFFER_BIT
 
-               frame_core_sprites(display, ui_sprites.as(SpriteSet), ui_camera)
+               frame_core_sprites(display, ui_sprites, ui_camera)
        end
 end
 
@@ -687,7 +687,7 @@ private class Simple2dProgram
                        vec3 c; // coords
 
                        float end = a_start + a_loops/a_fps*a_n_frames;
-                       if (a_loops == -1.0 || time < end) {
+                       if (a_fps != 0.0 && (a_loops == -1.0 || time < end)) {
                                // in animation
                                float frame = mod(floor((time-a_start)*a_fps), a_n_frames);
                                v_coord = a_tex_coord + a_tex_diff*frame;
@@ -875,26 +875,26 @@ redef class OffsetPoint3d
 end
 
 # Set of sprites sorting them into different `SpriteContext`
-private class SpriteSet
+class SpriteSet
        super HashSet[Sprite]
 
-       # Map texture then static vs dynamic to a `SpriteContext`
-       var contexts_map = new HashMap4[RootTexture, nullable RootTexture, Bool, Int, Array[SpriteContext]]
-
-       # Contexts in `contexts_map`, sorted by draw order
-       var contexts_items = new Array[SpriteContext]
-
-       # Sprites needing resorting in `contexts_map`
-       var sprites_to_remap = new Array[Sprite]
-
        # Animation speed multiplier (0.0 to pause, 1.0 for normal speed, etc.)
        var time_mod = 1.0 is writable
 
        # Seconds elapsed since the launch of the program, in world time responding to `time_mod`
        var time = 0.0
 
+       # Map texture then static vs dynamic to a `SpriteContext`
+       private var contexts_map = new HashMap4[RootTexture, nullable RootTexture, Bool, Int, Array[SpriteContext]]
+
+       # Contexts in `contexts_map`, sorted by draw order
+       private var contexts_items = new Array[SpriteContext]
+
+       # Sprites needing resorting in `contexts_map`
+       private var sprites_to_remap = new Array[Sprite]
+
        # Add a sprite to the appropriate context
-       fun map_sprite(sprite: Sprite)
+       private fun map_sprite(sprite: Sprite)
        do
                assert sprite.context == null else print_error "Sprite {sprite} belongs to another SpriteSet"
 
@@ -946,7 +946,7 @@ private class SpriteSet
        end
 
        # Remove a sprite from its context
-       fun unmap_sprite(sprite: Sprite)
+       private fun unmap_sprite(sprite: Sprite)
        do
                var context = sprite.context
                assert context != null
@@ -957,10 +957,14 @@ private class SpriteSet
        end
 
        # Draw all sprites by all contexts
-       fun draw
+       private fun draw
        do
                # Remap sprites that may need to change context
                for sprite in sprites_to_remap do
+
+                       # Skip if it was removed from this set after being modified
+                       if sprite.context != self then continue
+
                        unmap_sprite sprite
                        map_sprite sprite
                end
@@ -1211,8 +1215,12 @@ private class SpriteContext
                                data[o+36] = tc[v*2+1]
 
                                # a_tex_diff
-                               var dx = animation.frames[1].texture_coords[0] - animation.frames[0].texture_coords[0]
-                               var dy = animation.frames[1].texture_coords[1] - animation.frames[0].texture_coords[1]
+                               var dx = 0.0
+                               var dy = 0.0
+                               if animation.frames.length > 1 then
+                                       dx = animation.frames[1].texture_coords[0] - animation.frames[0].texture_coords[0]
+                                       dy = animation.frames[1].texture_coords[1] - animation.frames[0].texture_coords[1]
+                               end
                                data[o+37] = dx
                                data[o+38] = dy
 
index b0c4241..b86f8e5 100644 (file)
@@ -37,6 +37,7 @@ redef class App
                        if sdl_event isa SDLWindowEvent and sdl_event.is_resized then
                                display.width = sdl_event.data1
                                display.height = sdl_event.data2
+                               display.aspect_ratio = sdl_event.data1.to_f / sdl_event.data2.to_f
                                on_resize display
                        end
 
@@ -47,6 +48,10 @@ redef class App
        end
 end
 
+redef class GamnitDisplay
+       redef var aspect_ratio = super is lazy
+end
+
 # ---
 # Redef services from `sdl2::events`