Browse code

add label scenimp node

devnewton authored on 27/09/2015 14:07:33
Showing 14 changed files
... ...
@@ -32,6 +32,7 @@ include_directories(${SDL2_TTF_INCLUDE_DIR})
32 32
 add_executable(superpaflaballe
33 33
  src/bourrines_benchmark.cpp
34 34
  src/scenimp/assets.cpp
35
+ src/scenimp/label.cpp
35 36
  src/scenimp/scene.cpp
36 37
  src/scenimp/screen.cpp
37 38
  src/scenimp/sprite.cpp
... ...
@@ -62,10 +62,10 @@ namespace superpaflaballe {
62 62
 
63 63
         virtual void process(bourrines::entity e) override {
64 64
             auto& sprite = get<sprite_component>(e).sprite_;
65
-
66 65
             sprite->set_angle(sprite->angle() + 1.0);
67 66
 
68
-            auto& pos = sprite->pos();
67
+            auto& group = get<sprite_component>(e).group_;
68
+            auto& pos = group->pos();
69 69
             dir_component& dir = get<dir_component>(e);
70 70
             pos.x(pos.x() + dir.dx_);
71 71
             pos.y(pos.y() + dir.dy_);
... ...
@@ -98,7 +98,7 @@ namespace superpaflaballe {
98 98
         virtual void process() override {
99 99
             scene_.render();
100 100
         }
101
-        
101
+
102 102
     private:
103 103
         scenimp::scene& scene_;
104 104
     };
... ...
@@ -109,6 +109,8 @@ namespace superpaflaballe {
109 109
     , remaining_ticks_(num_ticks) {
110 110
         timer_.stop();
111 111
         ned_anim_ = screen.assets().animations("ned.json");
112
+        ned_font_ = screen_.assets().font("ProFontWindows.ttf", 12);
113
+
112 114
         world_.add_system(1, std::unique_ptr<hera_system>(new hera_system(*this, num_entity)));
113 115
         world_.add_system(2, std::unique_ptr<hades_system>(new hades_system()));
114 116
         world_.add_system(3, std::unique_ptr<move_system>(new move_system(screen)));
... ...
@@ -120,18 +122,27 @@ namespace superpaflaballe {
120 122
 
121 123
     void bourrines_benchmark::create_ned() {
122 124
         bourrines::entity e = world_.create_entity();
123
-        auto sprite = scene_.new_sprite();
124
-        world_.add<sprite_component>(e).sprite_ = sprite;
125
-        auto& pos = sprite->pos();
125
+        auto group = scene_.new_group();
126
+        auto sprite = scene_.new_sprite(group);
127
+        
128
+        auto& component = world_.add<sprite_component>(e);
129
+        component.sprite_ = sprite;
130
+        component.group_ = group;
126 131
 
132
+        auto& pos = group->pos();
127 133
         pos.x(std::rand() % screen_.logical_screen_width());
128 134
         pos.y(std::rand() % screen_.logical_screen_height());
129
-
135
+        
130 136
         dir_component& dir = world_.add<dir_component>(e);
131 137
         dir.dx_ = (1 + (std::rand() % 10)) * ((std::rand() % 1) ? -1 : 1);
132 138
         dir.dy_ = (1 + (std::rand() % 10)) * ((std::rand() % 1) ? -1 : 1);
133
-
134 139
         sprite->set_play(ned_anim_->play(scenimp::nanim::loop));
140
+
141
+        auto label = scene_.new_label(group);
142
+        label->set_font(ned_font_);
143
+        label->set_text("ned");
144
+        label->pos().y(32);
145
+
135 146
         world_.add<life_component>(e).life_ = remaining_ticks_ > 0 ? std::rand() % remaining_ticks_ : 1;
136 147
 
137 148
         world_.changed(e);
... ...
@@ -19,11 +19,12 @@ namespace superpaflaballe {
19 19
     };
20 20
 
21 21
     struct sprite_component {
22
+        std::shared_ptr<scenimp::group> group_;
22 23
         std::shared_ptr<scenimp::sprite> sprite_;
23 24
         
24 25
         ~sprite_component() {
25
-            if(sprite_) {
26
-                sprite_->remove();
26
+            if(group_) {
27
+                group_->remove_from_parent();
27 28
             }
28 29
         }
29 30
     };
... ...
@@ -45,6 +46,7 @@ namespace superpaflaballe {
45 46
         scenimp::screen& screen_;
46 47
         scenimp::scene scene_;
47 48
         std::shared_ptr< scenimp::nanim::collection > ned_anim_;
49
+        std::shared_ptr< TTF_Font > ned_font_;
48 50
         boost::timer::auto_cpu_timer timer_;
49 51
         int remaining_ticks_;
50 52
     };
... ...
@@ -74,7 +74,7 @@ namespace superpaflaballe {
74 74
 
75 75
             state_benchmark(my_context ctx)
76 76
             : boost::statechart::state< state_benchmark, state_running >(ctx)
77
-            , benchmark_(this->outermost_context().screen_, 10000, 60 * 10) {
77
+            , benchmark_(this->outermost_context().screen_, 1000, 60 * 10) {
78 78
             }
79 79
 
80 80
             boost::statechart::result react(const event_tick&) {
... ...
@@ -104,8 +104,6 @@ int main(int, char**) {
104 104
 
105 105
         superpaflaballe::statechart::event_sdl event_sdl;
106 106
         superpaflaballe::statechart::event_tick event_tick;
107
-        auto font = machine.screen_.assets().font("ProFontWindows.ttf", 12);
108
-        auto text_texture = machine.screen_.create_text_texture(font, "plop");
109 107
         
110 108
         FPSmanager fps;
111 109
         SDL_initFramerate(&fps);
... ...
@@ -116,7 +114,6 @@ int main(int, char**) {
116 114
             }
117 115
             SDL_RenderClear(machine.screen_.renderer());
118 116
             machine.process_event(event_tick);
119
-            SDL_RenderCopy(machine.screen_.renderer(), text_texture.get(), nullptr, nullptr);
120 117
             SDL_RenderPresent(machine.screen_.renderer());
121 118
             SDL_framerateDelay(&fps);
122 119
         }
... ...
@@ -18,14 +18,14 @@ namespace scenimp {
18 18
             n->render(r);
19 19
         }
20 20
     }
21
-    void group::add(std::shared_ptr< node > node) {
21
+    void group::add_child(std::shared_ptr< node > node) {
22 22
         if(node->parent_.lock()) {
23 23
             throw new std::runtime_error("node is already in a group");
24 24
         }
25 25
         node->parent_ = std::static_pointer_cast<group>( shared_from_this() );
26 26
         children_.insert(node);
27 27
     }
28
-    void group::remove(std::shared_ptr< node > node) {
28
+    void group::remove_child(std::shared_ptr< node > node) {
29 29
         if(node->parent_.lock() != shared_from_this()) {
30 30
             throw new std::runtime_error("cannot remove a node that does not belong to this group");
31 31
         }
... ...
@@ -16,8 +16,8 @@ namespace scenimp {
16 16
         virtual ~group();
17 17
 
18 18
         const node_set& children() const;
19
-        void add(std::shared_ptr< node > node);
20
-        void remove(std::shared_ptr< node > node);
19
+        void add_child(std::shared_ptr< node > node);
20
+        void remove_child(std::shared_ptr< node > node);
21 21
 
22 22
     protected:
23 23
         virtual void do_render(rendering& r);
24 24
new file mode 100644
... ...
@@ -0,0 +1,99 @@
1
+#include "label.h"
2
+#include "rendering.h"
3
+
4
+namespace scenimp {
5
+
6
+    const SDL_Color defaultLabelColor = {255, 255, 255, 0};
7
+
8
+    label::label()
9
+    : color_(defaultLabelColor)
10
+    , angle_(0.0)
11
+    , width_(-1)
12
+    , height_(-1)
13
+    , flip_(SDL_FLIP_NONE) {
14
+    }
15
+
16
+    label::~label() {
17
+    }
18
+
19
+    void label::do_render(rendering& r) {
20
+        if (font_ && !text_.empty()) {
21
+            const point& pos = r.current_pos();
22
+            update(r);
23
+            SDL_Rect rect_ = {pos.x() + -width_ / 2, pos.y() + -height_ / 2, width_, height_};
24
+            SDL_RenderCopyEx(r.renderer(), texture_.get(), NULL, &rect_, angle_, NULL, flip_);
25
+        }
26
+    }
27
+
28
+    const std::string& label::text() const {
29
+        return text_;
30
+    }
31
+
32
+    void label::set_text(const std::string& t) {
33
+        text_ = t;
34
+        set_dirty();
35
+    }
36
+
37
+    std::shared_ptr< TTF_Font > label::font() {
38
+        return font_;
39
+    }
40
+
41
+    void label::set_font(std::shared_ptr< TTF_Font > font) {
42
+        font_ = font;
43
+        set_dirty();
44
+    }
45
+
46
+    const SDL_Color& label::color() const {
47
+        return color_;
48
+    }
49
+
50
+    void label::set_color(const SDL_Color& color) {
51
+        color_ = color;
52
+        set_dirty();
53
+    }
54
+
55
+    void label::set_dirty() {
56
+        texture_.reset();
57
+    }
58
+
59
+    void label::update(rendering& r) {
60
+        if (!texture_) {
61
+            std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *) > text_surface(TTF_RenderText_Blended(font_.get(), text_.c_str(), color_), SDL_FreeSurface);
62
+            texture_ = std::shared_ptr< SDL_Texture >(SDL_CreateTextureFromSurface(r.renderer(), text_surface.get()), SDL_DestroyTexture);
63
+        }
64
+        if (texture_ && (width_ < 0 || height_ < 0)) {
65
+            SDL_QueryTexture(texture_.get(),
66
+                    NULL,
67
+                    NULL,
68
+                    &width_,
69
+                    &height_);
70
+        }
71
+    }
72
+
73
+    SDL_RendererFlip label::flip() const {
74
+        return flip_;
75
+    }
76
+
77
+    void label::set_flip(SDL_RendererFlip flip) {
78
+        flip_ = flip;
79
+    }
80
+
81
+    double label::angle()const {
82
+        return angle_;
83
+    }
84
+
85
+    void label::set_angle(double a) {
86
+        angle_ = a;
87
+    }
88
+
89
+    void label::set_fixed_size(int w, int h) {
90
+        width_ = w;
91
+        height_ = h;
92
+    }
93
+
94
+    void label::set_dynamic_size() {
95
+        width_ = -1;
96
+        height_ = -1;
97
+    }
98
+
99
+}
0 100
new file mode 100644
... ...
@@ -0,0 +1,53 @@
1
+#pragma once
2
+
3
+#include "node.h"
4
+#include "rendering.h"
5
+#include <SDL_ttf.h>
6
+
7
+namespace scenimp {
8
+
9
+    class label : public node {
10
+    public:
11
+        label();
12
+        label(const label& orig) = delete;
13
+        virtual ~label();
14
+
15
+        const std::string& text() const;
16
+        void set_text(const std::string& t);
17
+
18
+        std::shared_ptr< TTF_Font > font();
19
+        void set_font(std::shared_ptr< TTF_Font > font);
20
+
21
+        const SDL_Color& color() const;
22
+        void set_color(const SDL_Color& color);
23
+
24
+        SDL_RendererFlip flip() const;
25
+        void set_flip(SDL_RendererFlip flip);
26
+
27
+        double angle()const;
28
+        void set_angle(double a);
29
+
30
+        void set_fixed_size(int w, int h);
31
+        void set_dynamic_size();
32
+
33
+    protected:
34
+        virtual void do_render(rendering& r) override;
35
+
36
+    private:
37
+        void set_dirty();
38
+        void update(rendering& r);
39
+
40
+        std::string text_;
41
+        SDL_Color color_;
42
+        std::shared_ptr< TTF_Font > font_;
43
+        std::shared_ptr< SDL_Texture > texture_;
44
+        double angle_;
45
+        int width_;
46
+        int height_;
47
+        SDL_RendererFlip flip_;
48
+
49
+    };
50
+
51
+}
52
+
53
+
... ...
@@ -11,9 +11,9 @@ namespace scenimp {
11 11
     node::~node() {
12 12
     }
13 13
     
14
-    void node::remove() {
14
+    void node::remove_from_parent() {
15 15
         if(auto parent = parent_.lock()) {
16
-            parent->remove(shared_from_this());
16
+            parent->remove_child(shared_from_this());
17 17
         }
18 18
     }
19 19
 
... ...
@@ -14,7 +14,7 @@ namespace scenimp {
14 14
         node(const node&) = delete;
15 15
         virtual ~node();
16 16
         
17
-        void remove();
17
+        void remove_from_parent();
18 18
         
19 19
         void render(rendering& r);
20 20
 
... ...
@@ -18,7 +18,7 @@ namespace scenimp {
18 18
         if (!parent) {
19 19
             parent = root_;
20 20
         }
21
-        parent->add(g);
21
+        parent->add_child(g);
22 22
         return g;
23 23
     }
24 24
 
... ...
@@ -27,9 +27,18 @@ namespace scenimp {
27 27
         if (!parent) {
28 28
             parent = root_;
29 29
         }
30
-        parent->add(s);
30
+        parent->add_child(s);
31 31
         return s;
32 32
     }
33
+    
34
+    std::shared_ptr<label> scene::new_label(std::shared_ptr<group> parent) {
35
+        auto l = std::make_shared<label>();
36
+        if (!parent) {
37
+            parent = root_;
38
+        }
39
+        parent->add_child(l);
40
+        return l;
41
+    }
33 42
 
34 43
     void scene::render() {
35 44
         rendering r(renderer_);
... ...
@@ -1,5 +1,6 @@
1 1
 #pragma once
2 2
 
3
+#include "label.h"
3 4
 #include "group.h"
4 5
 #include "sprite.h"
5 6
 #include <SDL.h>
... ...
@@ -14,6 +15,7 @@ namespace scenimp {
14 15
         
15 16
         std::shared_ptr< group > new_group(std::shared_ptr< group > parent = nullptr);
16 17
         std::shared_ptr< sprite > new_sprite(std::shared_ptr< group > parent = nullptr);
18
+        std::shared_ptr< label > new_label(std::shared_ptr< group > parent = nullptr);
17 19
 
18 20
         void render();
19 21
 
... ...
@@ -51,9 +51,4 @@ namespace scenimp {
51 51
         return *assets_;
52 52
     }
53 53
 
54
-    std::shared_ptr< SDL_Texture > screen::create_text_texture(std::shared_ptr< TTF_Font > font, const std::string& str, const SDL_Color& color) {
55
-        std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *) > text_surface(TTF_RenderText_Blended(font.get(), str.c_str(), color), SDL_FreeSurface);
56
-        return std::shared_ptr< SDL_Texture >(SDL_CreateTextureFromSurface(renderer(), text_surface.get()), SDL_DestroyTexture);
57
-    }
58
-
59 54
 }
... ...
@@ -16,8 +16,6 @@ namespace scenimp {
16 16
         SDL_Renderer* renderer();
17 17
         scenimp::assets& assets();
18 18
 
19
-        std::shared_ptr< SDL_Texture > create_text_texture(std::shared_ptr< TTF_Font > font, const std::string& str, const SDL_Color& color = {255, 255, 255, 0});
20
-
21 19
     private:
22 20
         scenimp::assets* assets_;
23 21
         SDL_Window* window_;