Also register the window builders.

Still has an oddity that the linker seems too smart for its own good,
producing broken binaries... ah well a work-around is in place.
This commit is contained in:
Mark de Wever 2010-04-02 15:25:08 +00:00
parent 28f5876306
commit 56dbb06467
26 changed files with 153 additions and 47 deletions

View file

@ -20,37 +20,32 @@
#include "foreach.hpp"
#include "gettext.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/window_builder/button.hpp"
#include "gui/auxiliary/window_builder/helper.hpp"
#include "gui/auxiliary/window_builder/horizontal_listbox.hpp"
#include "gui/auxiliary/window_builder/horizontal_scrollbar.hpp"
#include "gui/auxiliary/window_builder/image.hpp"
#include "gui/auxiliary/window_builder/label.hpp"
#include "gui/auxiliary/window_builder/listbox.hpp"
#include "gui/auxiliary/window_builder/minimap.hpp"
#include "gui/auxiliary/window_builder/multi_page.hpp"
#include "gui/auxiliary/window_builder/repeating_button.hpp"
#include "gui/auxiliary/window_builder/scroll_label.hpp"
#if 1 // See the #if in create_builder_widget.
#include "gui/auxiliary/window_builder/scrollbar_panel.hpp"
#include "gui/auxiliary/window_builder/slider.hpp"
#include "gui/auxiliary/window_builder/spacer.hpp"
#include "gui/auxiliary/window_builder/horizontal_scrollbar.hpp"
#include "gui/auxiliary/window_builder/repeating_button.hpp"
#include "gui/auxiliary/window_builder/stacked_widget.hpp"
#include "gui/auxiliary/window_builder/text_box.hpp"
#include "gui/auxiliary/window_builder/toggle_button.hpp"
#include "gui/auxiliary/window_builder/tree_view.hpp"
#include "gui/auxiliary/window_builder/panel.hpp"
#include "gui/auxiliary/window_builder/password_box.hpp"
#include "gui/auxiliary/window_builder/progress_bar.hpp"
#include "gui/auxiliary/window_builder/toggle_panel.hpp"
#include "gui/auxiliary/window_builder/vertical_scrollbar.hpp"
#endif
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "formula_string_utils.hpp"
#include <boost/bind.hpp>
namespace gui2 {
namespace {
static std::map<std::string, boost::function<tbuilder_widget_ptr(config)> >&
builder_widget_lookup()
{
static std::map<std::string, boost::function<tbuilder_widget_ptr(config)> >
result;
return result;
}
tbuilder_widget_ptr create_builder_widget(const config& cfg)
{
config::all_children_itors children = cfg.all_children_range();
@ -62,39 +57,51 @@ tbuilder_widget_ptr create_builder_widget(const config& cfg)
assert(false);
}
#define TRY(name) do { \
if (const config &c = cfg.child(#name)) \
return new tbuilder_##name(c); \
typedef
std::pair<
std::string
, boost::function<tbuilder_widget_ptr(config)> >
thack;
foreach(const thack& item, builder_widget_lookup()) {
if(item.first == "window" || item.first == "tooltip") {
continue;
}
if(const config &c = cfg.child(item.first)) {
return item.second(c);
}
}
if(const config &c = cfg.child("grid")) {
return new tbuilder_grid(c);
}
/*
* This is rather odd, when commented out the classes no longer seem to be in
* the executable, no real idea why, except maybe of an overzealous optimizer
* while linking. It seems that all these classes aren't explicitly
* instantiated but only implicitly. Also when looking at the symbols in
* libwesnoth-game.a the repeating button is there regardless of this #if but
* in the final binary only if the #if is enabled.
*
* If this code is executed, which it will cause an assertion failure.
*/
#if 1
#define TRY(name) \
do { \
if(const config &c = cfg.child(#name)) { \
tbuilder_widget_ptr p = new implementation::tbuilder_##name(c);\
assert(false); \
} \
} while (0)
// The widgets builders are mostly in this namespace.
using namespace gui2::implementation;
TRY(button);
TRY(horizontal_listbox);
TRY(horizontal_scrollbar);
TRY(image);
TRY(label);
TRY(listbox);
TRY(minimap);
TRY(multi_page);
TRY(panel);
TRY(repeating_button);
TRY(scroll_label);
TRY(scrollbar_panel);
TRY(slider);
TRY(spacer);
TRY(stacked_widget);
TRY(text_box);
TRY(password_box);
TRY(progress_bar);
TRY(toggle_button);
TRY(toggle_panel);
TRY(tree_view);
TRY(scrollbar_panel);
TRY(horizontal_scrollbar);
TRY(repeating_button);
TRY(vertical_scrollbar);
TRY(grid);
#undef TRY
#endif
std::cerr << cfg;
ERROR_LOG(false);
@ -172,6 +179,12 @@ twindow* build(CVideo& video, const std::string& type)
return window;
}
void register_builder_widget(const std::string& id
, boost::function<tbuilder_widget_ptr(config)> functor)
{
builder_widget_lookup().insert(std::make_pair(id, functor));
}
const std::string& twindow_builder::read(const config& cfg)
{
/*WIKI

View file

@ -18,6 +18,8 @@
#include "gui/auxiliary/formula.hpp"
#include "reference_counted_object.hpp"
#include <boost/function.hpp>
#include <string>
#include <vector>
@ -32,6 +34,7 @@ class twindow;
twindow* build(CVideo& video, const std::string& type);
/** Contains the info needed to instantiate a widget. */
struct tbuilder_widget : public reference_counted_object
{
@ -49,6 +52,34 @@ public:
typedef boost::intrusive_ptr<tbuilder_widget> tbuilder_widget_ptr;
typedef boost::intrusive_ptr<const tbuilder_widget> const_tbuilder_widget_ptr;
/**
* Registers a widget to be build.
*
* @warning This function runs before @ref main() so needs to be careful
* regarding the static initialization problem.
*
* @param id The id of the widget as used in WML.
* @param functor The functor to create the widget.
*/
void register_builder_widget(const std::string& id
, boost::function<tbuilder_widget_ptr(config)> functor);
/**
* Helper to generate a widget from a WML widget instance.
*
* Mainly used as functor for @ref register_builder_widget.
*
* @param cfg The config with the information to
* instanciate the widget.
*
* @returns A generic widget builder pointer.
*/
template<class T>
tbuilder_widget_ptr build_widget(const config& cfg)
{
return new T(cfg);
}
struct tbuilder_grid : public tbuilder_widget
{
private:

View file

@ -18,6 +18,7 @@
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/button.hpp"
#include "gui/auxiliary/window_builder/button.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "sound.hpp"

View file

@ -18,6 +18,7 @@
#include "gui/widgets/settings.hpp"
#include "gui/auxiliary/widget_definition/horizontal_scrollbar.hpp"
#include "gui/auxiliary/window_builder/horizontal_scrollbar.hpp"
#include <boost/bind.hpp>

View file

@ -18,6 +18,7 @@
#include "../../image.hpp"
#include "gui/auxiliary/widget_definition/image.hpp"
#include "gui/auxiliary/window_builder/image.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/widgets/settings.hpp"

View file

@ -17,6 +17,7 @@
#include "gui/widgets/label.hpp"
#include "gui/auxiliary/widget_definition/label.hpp"
#include "gui/auxiliary/window_builder/label.hpp"
#include "gui/widgets/settings.hpp"
#include <boost/bind.hpp>

View file

@ -19,6 +19,8 @@
#include "gui/auxiliary/layout_exception.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/listbox.hpp"
#include "gui/auxiliary/window_builder/listbox.hpp"
#include "gui/auxiliary/window_builder/horizontal_listbox.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"

View file

@ -18,6 +18,7 @@
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/minimap.hpp"
#include "gui/auxiliary/window_builder/minimap.hpp"
#include "gui/widgets/settings.hpp"
#include "map.hpp"
#include "map_exception.hpp"

View file

@ -17,6 +17,7 @@
#include "gui/widgets/multi_page.hpp"
#include "gui/auxiliary/widget_definition/multi_page.hpp"
#include "gui/auxiliary/window_builder/multi_page.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/generator.hpp"

View file

@ -18,6 +18,7 @@
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/panel.hpp"
#include "gui/auxiliary/window_builder/panel.hpp"
#include "gui/widgets/settings.hpp"
#include <boost/bind.hpp>

View file

@ -19,6 +19,7 @@
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/text_box.hpp"
#include "gui/auxiliary/window_builder/password_box.hpp"
#include "gui/widgets/settings.hpp"
#include "serialization/string_utils.hpp"

View file

@ -17,6 +17,7 @@
#include "gui/widgets/progress_bar.hpp"
#include "gui/auxiliary/widget_definition/progress_bar.hpp"
#include "gui/auxiliary/window_builder/progress_bar.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/widgets/settings.hpp"

View file

@ -19,6 +19,7 @@
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/timer.hpp"
#include "gui/auxiliary/widget_definition/repeating_button.hpp"
#include "gui/auxiliary/window_builder/repeating_button.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "sound.hpp"

View file

@ -19,6 +19,7 @@
#include "gui/widgets/label.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/scroll_label.hpp"
#include "gui/auxiliary/window_builder/scroll_label.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/scrollbar.hpp"
#include "gui/widgets/spacer.hpp"

View file

@ -17,6 +17,7 @@
#include "gui/widgets/scrollbar_panel.hpp"
#include "gui/auxiliary/widget_definition/scrollbar_panel.hpp"
#include "gui/auxiliary/window_builder/scrollbar_panel.hpp"
#include "gui/widgets/settings.hpp"
#include <boost/bind.hpp>

View file

@ -20,6 +20,7 @@
#include "formatter.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/slider.hpp"
#include "gui/auxiliary/window_builder/slider.hpp"
#include "gui/widgets/settings.hpp"
#include "sound.hpp"

View file

@ -17,6 +17,7 @@
#include "gui/widgets/spacer.hpp"
#include "gui/auxiliary/widget_definition/spacer.hpp"
#include "gui/auxiliary/window_builder/spacer.hpp"
#include "gui/widgets/settings.hpp"
#include <boost/bind.hpp>

View file

@ -18,6 +18,7 @@
#include "foreach.hpp"
#include "gui/auxiliary/widget_definition/stacked_widget.hpp"
#include "gui/auxiliary/window_builder/stacked_widget.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/generator.hpp"

View file

@ -20,6 +20,7 @@
#include "foreach.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/text_box.hpp"
#include "gui/auxiliary/window_builder/text_box.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "game_preferences.hpp"

View file

@ -19,6 +19,7 @@
#include "foreach.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/toggle_button.hpp"
#include "gui/auxiliary/window_builder/toggle_button.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "sound.hpp"

View file

@ -19,6 +19,7 @@
#include "foreach.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/toggle_panel.hpp"
#include "gui/auxiliary/window_builder/toggle_panel.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"
#include "sound.hpp"

View file

@ -17,12 +17,31 @@
#include "gui/widgets/tooltip.hpp"
#include "gui/auxiliary/widget_definition/tooltip.hpp"
#include "gui/auxiliary/window_builder/control.hpp"
#include "gui/widgets/settings.hpp"
#include <boost/bind.hpp>
namespace gui2 {
namespace implementation {
/** @todo See whether this hack can be removed. */
// Needed to fix a compiler error in REGISTER_WIDGET.
class tbuilder_tooltip
: public tbuilder_control
{
public:
tbuilder_tooltip(const config& cfg)
: tbuilder_control(cfg)
{
}
twidget* build() const { return NULL; }
};
} // namespace implementation
REGISTER_WIDGET(tooltip)
const std::string& ttooltip::get_control_type() const

View file

@ -18,6 +18,7 @@
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/widget_definition/tree_view.hpp"
#include "gui/auxiliary/window_builder/tree_view.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/tree_view_node.hpp"
#include "gui/widgets/window.hpp"

View file

@ -17,6 +17,7 @@
#include "gui/widgets/vertical_scrollbar.hpp"
#include "gui/auxiliary/widget_definition/vertical_scrollbar.hpp"
#include "gui/auxiliary/window_builder/vertical_scrollbar.hpp"
#include "gui/widgets/settings.hpp"
#include <boost/bind.hpp>

View file

@ -780,6 +780,10 @@ namespace { \
, _2 \
, _3 \
, key)); \
\
register_builder_widget(#id, boost::bind( \
build_widget<implementation::tbuilder_##id> \
, _1)); \
} \
}; \
\

View file

@ -29,6 +29,7 @@
#include "gui/auxiliary/event/distributor.hpp"
#include "gui/auxiliary/log.hpp"
#include "gui/auxiliary/layout_exception.hpp"
#include "gui/auxiliary/window_builder/control.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/settings.hpp"
#ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
@ -50,6 +51,22 @@
namespace gui2{
namespace implementation {
/** @todo See whether this hack can be removed. */
// Needed to fix a compiler error in REGISTER_WIDGET.
class tbuilder_window
: public tbuilder_control
{
public:
tbuilder_window(const config& cfg)
: tbuilder_control(cfg)
{
}
twidget* build() const { return NULL; }
};
} // namespace implementation
REGISTER_WIDGET(window)
unsigned twindow::sunset_ = 0;