gameui
changeset 5:5a84873185ff tip
rudimentary theme plugin system and other minor fixes
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 22 Mar 2014 01:50:01 +0200 |
parents | e0916bb20b7f |
children | |
files | Makefile include/button.h include/event.h include/goatkit.h include/label.h include/vec.h include/widget.h src/button.cc src/event.h src/label.cc src/theme.cc src/theme.h src/vec.h src/widget.cc themes/simple/Makefile themes/simple/simple.cc |
diffstat | 16 files changed, 248 insertions(+), 86 deletions(-) [+] |
line diff
1.1 --- a/Makefile Fri Mar 21 21:45:37 2014 +0200 1.2 +++ b/Makefile Sat Mar 22 01:50:01 2014 +0200 1.3 @@ -1,15 +1,25 @@ 1.4 src = test.cc $(wildcard src/*.cc) 1.5 obj = $(src:.cc=.o) 1.6 +dep = $(obj:.o=.d) 1.7 1.8 bin = test 1.9 1.10 CFLAGS = -pedantic -Wall -g -Iinclude -Isrc 1.11 CXXFLAGS = $(CFLAGS) 1.12 -LDFLAGS = -lGL -lGLU -lglut -lpthread 1.13 +LDFLAGS = -lGL -lGLU -lglut -lpthread -ldl 1.14 1.15 $(bin): $(obj) 1.16 $(CXX) -o $@ $(obj) $(LDFLAGS) 1.17 1.18 +-include $(dep) 1.19 + 1.20 + 1.21 +%.d: %.c 1.22 + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 1.23 + 1.24 +%.d: %.cc 1.25 + @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ 1.26 + 1.27 .PHONY: clean 1.28 clean: 1.29 - rm -f $(obj) $(bin) 1.30 + rm -f $(obj) $(bin) $(dep)
2.1 --- a/include/button.h Fri Mar 21 21:45:37 2014 +0200 2.2 +++ b/include/button.h Sat Mar 22 01:50:01 2014 +0200 2.3 @@ -14,6 +14,8 @@ 2.4 public: 2.5 Button(); 2.6 virtual ~Button(); 2.7 + 2.8 + virtual const char *get_type_name() const; 2.9 }; 2.10 2.11 } // namespace goatkit
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/include/event.h Sat Mar 22 01:50:01 2014 +0200 3.3 @@ -0,0 +1,45 @@ 3.4 +#ifndef EVENT_H_ 3.5 +#define EVENT_H_ 3.6 + 3.7 +#include "vec.h" 3.8 + 3.9 +namespace goatkit { 3.10 + 3.11 +enum EventType { 3.12 + EV_MOUSE_BUTTON, 3.13 + EV_MOUSE_MOTION, 3.14 + EV_MOUSE_FOCUS, 3.15 + EV_KEY 3.16 +}; 3.17 + 3.18 +struct ButtonEvent { 3.19 + Vec2 pos; 3.20 + int button; 3.21 + bool press; 3.22 +}; 3.23 + 3.24 +struct MotionEvent { 3.25 + Vec2 pos; 3.26 +}; 3.27 + 3.28 +struct FocusEvent { 3.29 + bool enter; 3.30 +}; 3.31 + 3.32 +struct KeyEvent { 3.33 + int key; 3.34 + bool press; 3.35 +}; 3.36 + 3.37 +struct Event { 3.38 + EventType type; 3.39 + 3.40 + ButtonEvent button; 3.41 + MotionEvent motion; 3.42 + FocusEvent focus; 3.43 + KeyEvent key; 3.44 +}; 3.45 + 3.46 +} // namespace goatkit 3.47 + 3.48 +#endif // EVENT_H_
4.1 --- a/include/goatkit.h Fri Mar 21 21:45:37 2014 +0200 4.2 +++ b/include/goatkit.h Sat Mar 22 01:50:01 2014 +0200 4.3 @@ -4,5 +4,10 @@ 4.4 #include "widget.h" 4.5 #include "button.h" 4.6 #include "label.h" 4.7 +#include "event.h" 4.8 + 4.9 +namespace goatkit { 4.10 + typedef void (*WidgetDrawFunc)(const Widget*); 4.11 +} 4.12 4.13 #endif // GOATKIT_H_
5.1 --- a/include/label.h Fri Mar 21 21:45:37 2014 +0200 5.2 +++ b/include/label.h Sat Mar 22 01:50:01 2014 +0200 5.3 @@ -1,17 +1,21 @@ 5.4 #ifndef GOATKIT_LABEL_H_ 5.5 #define GOATKIT_LABEL_H_ 5.6 5.7 +#include "widget.h" 5.8 + 5.9 namespace goatkit { 5.10 5.11 class LabelImpl; 5.12 5.13 -class Label { 5.14 +class Label : public Widget { 5.15 private: 5.16 - LabelImpl *impl; 5.17 + LabelImpl *label; 5.18 5.19 public: 5.20 Label(); 5.21 virtual ~Label(); 5.22 + 5.23 + virtual const char *get_type_name() const; 5.24 }; 5.25 5.26 } // namespace goatkit
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/include/vec.h Sat Mar 22 01:50:01 2014 +0200 6.3 @@ -0,0 +1,16 @@ 6.4 +#ifndef VEC_H_ 6.5 +#define VEC_H_ 6.6 + 6.7 +namespace goatkit { 6.8 + 6.9 +class Vec2 { 6.10 +public: 6.11 + float x, y; 6.12 + 6.13 + Vec2() : x(0), y(0) {} 6.14 + Vec2(float xx, float yy) : x(xx), y(yy) {} 6.15 +}; 6.16 + 6.17 +} // namespace goatkit 6.18 + 6.19 +#endif // VEC_H_
7.1 --- a/include/widget.h Fri Mar 21 21:45:37 2014 +0200 7.2 +++ b/include/widget.h Sat Mar 22 01:50:01 2014 +0200 7.3 @@ -16,12 +16,12 @@ 7.4 private: 7.5 WidgetImpl *widget; 7.6 7.7 - void set_type_string(const char *type_str); 7.8 - 7.9 public: 7.10 Widget(); 7.11 virtual ~Widget(); 7.12 7.13 + virtual const char *get_type_name() const; 7.14 + 7.15 virtual void show(); 7.16 virtual void hide(); 7.17 virtual float get_visibility() const;
8.1 --- a/src/button.cc Fri Mar 21 21:45:37 2014 +0200 8.2 +++ b/src/button.cc Sat Mar 22 01:50:01 2014 +0200 8.3 @@ -15,4 +15,9 @@ 8.4 delete button; 8.5 } 8.6 8.7 +const char *Button::get_type_name() const 8.8 +{ 8.9 + return "button"; 8.10 +} 8.11 + 8.12 } // namespace goatkit
9.1 --- a/src/event.h Fri Mar 21 21:45:37 2014 +0200 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,45 +0,0 @@ 9.4 -#ifndef EVENT_H_ 9.5 -#define EVENT_H_ 9.6 - 9.7 -#include "vec.h" 9.8 - 9.9 -namespace goatkit { 9.10 - 9.11 -enum EventType { 9.12 - EV_MOUSE_BUTTON, 9.13 - EV_MOUSE_MOTION, 9.14 - EV_MOUSE_FOCUS, 9.15 - EV_KEY 9.16 -}; 9.17 - 9.18 -struct ButtonEvent { 9.19 - Vec2 pos; 9.20 - int button; 9.21 - bool press; 9.22 -}; 9.23 - 9.24 -struct MotionEvent { 9.25 - Vec2 pos; 9.26 -}; 9.27 - 9.28 -struct FocusEvent { 9.29 - bool enter; 9.30 -}; 9.31 - 9.32 -struct KeyEvent { 9.33 - int key; 9.34 - bool press; 9.35 -}; 9.36 - 9.37 -struct Event { 9.38 - EventType type; 9.39 - 9.40 - ButtonEvent button; 9.41 - MotionEvent motion; 9.42 - FocusEvent focus; 9.43 - KeyEvent key; 9.44 -}; 9.45 - 9.46 -} // namespace goatkit 9.47 - 9.48 -#endif // EVENT_H_
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/label.cc Sat Mar 22 01:50:01 2014 +0200 10.3 @@ -0,0 +1,23 @@ 10.4 +#include "label.h" 10.5 + 10.6 +namespace goatkit { 10.7 + 10.8 +struct LabelImpl { 10.9 +}; 10.10 + 10.11 +Label::Label() 10.12 +{ 10.13 + label = new LabelImpl; 10.14 +} 10.15 + 10.16 +Label::~Label() 10.17 +{ 10.18 + delete label; 10.19 +} 10.20 + 10.21 +const char *Label::get_type_name() const 10.22 +{ 10.23 + return "label"; 10.24 +} 10.25 + 10.26 +} // namespace goatkit
11.1 --- a/src/theme.cc Fri Mar 21 21:45:37 2014 +0200 11.2 +++ b/src/theme.cc Sat Mar 22 01:50:01 2014 +0200 11.3 @@ -1,10 +1,20 @@ 11.4 #include <stdio.h> 11.5 +#include <vector> 11.6 +#include <algorithm> 11.7 #include "theme.h" 11.8 #include "widget.h" 11.9 11.10 #ifdef WIN32 11.11 #include <windows.h> 11.12 + 11.13 +static void *dlopen(const char *name, int flags); 11.14 +static void dlclose(void *so); 11.15 +static void dlsym(void *so, const char *symbol); 11.16 +#else 11.17 +#include <unistd.h> 11.18 +#include <dlfcn.h> 11.19 #endif 11.20 + 11.21 #ifdef __APPLE__ 11.22 #include <OpenGL/gl.h> 11.23 #else 11.24 @@ -15,22 +25,89 @@ 11.25 namespace goatkit { 11.26 11.27 Theme *theme; 11.28 +static std::vector<std::string> search_paths; 11.29 + 11.30 + 11.31 +void add_theme_path(const char *path) 11.32 +{ 11.33 + if(!path || !*path) return; 11.34 + 11.35 + std::string s = path; 11.36 + int last = s.length() - 1; 11.37 + if(s[last] == '/' || s[last] == '\\') { 11.38 + s.erase(last); 11.39 + } 11.40 + 11.41 + if(std::find(search_paths.begin(), search_paths.end(), s) != search_paths.end()) { 11.42 + return; 11.43 + } 11.44 + 11.45 + search_paths.push_back(s); 11.46 +} 11.47 11.48 Theme::Theme() 11.49 { 11.50 so = 0; 11.51 } 11.52 11.53 +Theme::~Theme() 11.54 +{ 11.55 + unload(); 11.56 +} 11.57 + 11.58 +typedef WidgetDrawFunc (*LookupFunc)(const char*); 11.59 + 11.60 bool Theme::load(const char *name) 11.61 { 11.62 - fprintf(stderr, "theme loading not implemented yet!\n"); 11.63 - return false; 11.64 + unload(); 11.65 + 11.66 + if(!(so = dlopen(name, RTLD_LAZY))) { 11.67 + for(size_t i=0; i<search_paths.size(); i++) { 11.68 + std::string path = search_paths[i] + std::string(name); 11.69 + 11.70 + if((so = dlopen(path.c_str(), RTLD_LAZY))) { 11.71 + break; 11.72 + } 11.73 + } 11.74 + 11.75 + if(!so) { 11.76 + fprintf(stderr, "%s: failed to load theme plugin: %s\n", __func__, name); 11.77 + return false; 11.78 + } 11.79 + } 11.80 + 11.81 + // loaded the shared object, now get the lookup function 11.82 + lookup_theme_draw_func = (LookupFunc)dlsym(so, "get_widget_count"); 11.83 + if(!lookup_theme_draw_func) { 11.84 + fprintf(stderr, "%s: invalid theme plugin %s\n", __func__, name); 11.85 + unload(); 11.86 + return false; 11.87 + } 11.88 + 11.89 + return true; 11.90 } 11.91 11.92 -widget_draw_func Theme::get_draw_func(const char *type) const 11.93 +void Theme::unload() 11.94 { 11.95 - std::map<std::string, widget_draw_func>::const_iterator it = draw_func.find(type); 11.96 - if(it == draw_func.end()) { 11.97 + if(so) { 11.98 + dlclose(so); 11.99 + so = 0; 11.100 + } 11.101 + func_cache.clear(); 11.102 +} 11.103 + 11.104 +WidgetDrawFunc Theme::get_draw_func(const char *type) const 11.105 +{ 11.106 + std::map<std::string, WidgetDrawFunc>::const_iterator it = func_cache.find(type); 11.107 + if(it == func_cache.end()) { 11.108 + // don't have it cached, try to look it up 11.109 + WidgetDrawFunc func; 11.110 + if(lookup_theme_draw_func && (func = lookup_theme_draw_func(type))) { 11.111 + func_cache[type] = func; 11.112 + return func; 11.113 + } 11.114 + 11.115 + // can't look it up, return the default 11.116 return default_draw_func; 11.117 } 11.118 return it->second; 11.119 @@ -98,3 +175,21 @@ 11.120 } 11.121 11.122 } // namespace goatkit 11.123 + 11.124 +#ifdef WIN32 11.125 +// XXX untested 11.126 +static void *dlopen(const char *name, int flags) 11.127 +{ 11.128 + return LoadLibrary(name); 11.129 +} 11.130 + 11.131 +static void dlclose(void *so) 11.132 +{ 11.133 + // TODO 11.134 +} 11.135 + 11.136 +static void dlsym(void *so, const char *symbol) 11.137 +{ 11.138 + return GetProcAddress(so, symbol); 11.139 +} 11.140 +#endif
12.1 --- a/src/theme.h Fri Mar 21 21:45:37 2014 +0200 12.2 +++ b/src/theme.h Sat Mar 22 01:50:01 2014 +0200 12.3 @@ -3,27 +3,29 @@ 12.4 12.5 #include <string> 12.6 #include <map> 12.7 +#include "goatkit.h" 12.8 12.9 namespace goatkit { 12.10 12.11 class Widget; 12.12 12.13 -typedef void (*widget_draw_func)(const Widget*); 12.14 - 12.15 +void add_theme_path(const char *path); 12.16 void default_draw_func(const Widget *w); 12.17 12.18 class Theme { 12.19 private: 12.20 void *so; 12.21 - std::map<std::string, widget_draw_func> draw_func; 12.22 + WidgetDrawFunc (*lookup_theme_draw_func)(const char*); 12.23 + mutable std::map<std::string, WidgetDrawFunc> func_cache; 12.24 12.25 public: 12.26 Theme(); 12.27 ~Theme(); 12.28 12.29 bool load(const char *name); 12.30 + void unload(); 12.31 12.32 - widget_draw_func get_draw_func(const char *type) const; 12.33 + WidgetDrawFunc get_draw_func(const char *type) const; 12.34 }; 12.35 12.36 extern Theme *theme; // the current theme
13.1 --- a/src/vec.h Fri Mar 21 21:45:37 2014 +0200 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,16 +0,0 @@ 13.4 -#ifndef VEC_H_ 13.5 -#define VEC_H_ 13.6 - 13.7 -namespace goatkit { 13.8 - 13.9 -class Vec2 { 13.10 -public: 13.11 - float x, y; 13.12 - 13.13 - Vec2() : x(0), y(0) {} 13.14 - Vec2(float xx, float yy) : x(xx), y(yy) {} 13.15 -}; 13.16 - 13.17 -} // namespace goatkit 13.18 - 13.19 -#endif // VEC_H_
14.1 --- a/src/widget.cc Fri Mar 21 21:45:37 2014 +0200 14.2 +++ b/src/widget.cc Sat Mar 22 01:50:01 2014 +0200 14.3 @@ -9,7 +9,6 @@ 14.4 namespace goatkit { 14.5 14.6 struct WidgetImpl { 14.7 - std::string type_str; 14.8 std::string name; 14.9 BBox box; 14.10 14.11 @@ -22,10 +21,9 @@ 14.12 static int widget_count; 14.13 14.14 widget = new WidgetImpl; 14.15 - set_type_string("widget"); 14.16 14.17 std::stringstream sstr; 14.18 - sstr << widget->type_str << widget_count++; 14.19 + sstr << get_type_name() << widget_count++; 14.20 widget->name = sstr.str(); 14.21 14.22 widget->box.bmin = Vec2(0, 0); 14.23 @@ -43,6 +41,11 @@ 14.24 delete widget; 14.25 } 14.26 14.27 +const char *Widget::get_type_name() const 14.28 +{ 14.29 + return "widget"; 14.30 +} 14.31 + 14.32 void Widget::show() 14.33 { 14.34 widget->visible.change(true); 14.35 @@ -173,10 +176,10 @@ 14.36 14.37 void Widget::draw() const 14.38 { 14.39 - widget_draw_func draw_func = default_draw_func; 14.40 + WidgetDrawFunc draw_func = default_draw_func; 14.41 14.42 if(theme) { 14.43 - draw_func = theme->get_draw_func(widget->type_str.c_str()); 14.44 + draw_func = theme->get_draw_func(get_type_name()); 14.45 } 14.46 14.47 draw_func(this); 14.48 @@ -212,11 +215,6 @@ 14.49 } 14.50 14.51 14.52 -void Widget::set_type_string(const char *type_str) 14.53 -{ 14.54 - widget->type_str = type_str; 14.55 -} 14.56 - 14.57 /* the event dispatcher generates high-level events (click, etc) 14.58 * and calls the on_whatever() functions for both low and high-level 14.59 * events.
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/themes/simple/Makefile Sat Mar 22 01:50:01 2014 +0200 15.3 @@ -0,0 +1,12 @@ 15.4 +src = $(wildcard *.cc) 15.5 +obj = $(src:.cc=.o) 15.6 +lib_so = simple.so 15.7 + 15.8 +CXXFLAGS = -pedantic -Wall -g -I../../include 15.9 + 15.10 +$(lib_so): $(obj) 15.11 + $(CXX) -o $@ -shared $(obj) $(LDFLAGS) 15.12 + 15.13 +.PHONY: clean 15.14 +clean: 15.15 + rm -f $(obj) $(bin)