Skip to content
Permalink
Browse files

Merge branch 'make_shared_widgets'

* make_shared_widgets:
  UI: eliminate temp_window_factory_workaround()
  UI: use make_shared to create widget types
  UI: make dtors public to allow std::make_shared calls
  UI: factory: convert ObjectTypeFactory (from WidgetTypeFactory)
  RES: break lines in Makefile.res after 60+ chars
  • Loading branch information
tim-janik committed Apr 3, 2015
2 parents 6c2341f + f1886c7 commit 92fa5a8f34b20dbd4bac2fc23e17428d408c8648
Showing with 131 additions and 122 deletions.
  1. +2 −1 res/Makefile.am
  2. +3 −1 res/Makefile.res
  3. +45 −44 ui/factory.cc
  4. +19 −24 ui/factory.hh
  5. +4 −4 ui/layoutcontainers.hh
  6. +24 −0 ui/object.cc
  7. +15 −2 ui/object.hh
  8. +3 −3 ui/paintcontainers.hh
  9. +2 −2 ui/paintwidgets.hh
  10. +2 −2 ui/slider.hh
  11. +2 −22 ui/widget.cc
  12. +2 −4 ui/widget.hh
  13. +2 −8 ui/window.cc
  14. +6 −5 ui/window.hh
@@ -10,7 +10,8 @@ NEW_RES_DIRS := $(patsubst %/., %, $(wildcard $(addsuffix /., $(NEW_RES_PATHS))
NEW_RES_FILES := $(filter-out $(NEW_RES_DIRS), $(NEW_RES_PATHS))
Makefile.res: @INGIT@ $(if $(call streq, $(NEW_RES_FILES), $(RES_FILE_LIST)),, Makefile.tmp) $(NEW_RES_FILES)
$(AM_V_GEN)
$(Q) echo "RES_FILE_LIST = $(NEW_RES_FILES)" > Makefile.tmp
$(Q) echo "RES_FILE_LIST = $(NEW_RES_FILES)" | \
sed 's/\(.\{61\}[^ ]\+\) /\1 \\\n\t/g' > Makefile.tmp
$(Q) mv Makefile.tmp $@
Makefile.tmp: # MAKE(1) only remakes+rereads Makefiles with prerequisites, see (Remaking Makefiles)
$(Q) touch $@
@@ -1 +1,3 @@
RES_FILE_LIST = Rapicorn/foundation.xml Rapicorn/icons/broken-image.svg Rapicorn/icons/rapicorn.svg Rapicorn/icons/wm-gears.png Rapicorn/standard.xml Rapicorn/stock.ini themes/Default.xml
RES_FILE_LIST = Rapicorn/foundation.xml Rapicorn/icons/broken-image.svg \
Rapicorn/icons/rapicorn.svg Rapicorn/icons/wm-gears.png Rapicorn/standard.xml \
Rapicorn/stock.ini themes/Default.xml
@@ -97,74 +97,72 @@ static void initialize_factory_lazily (void);

namespace Factory {

// == WidgetTypeFactory ==
static std::list<const WidgetTypeFactory*>&
// == ObjectTypeFactory ==
static std::list<const ObjectTypeFactory*>&
widget_type_list()
{
static std::list<const WidgetTypeFactory*> *widget_type_factories_p = NULL;
static std::list<const ObjectTypeFactory*> *widget_type_factories_p = NULL;
do_once
{
widget_type_factories_p = new std::list<const WidgetTypeFactory*>();
widget_type_factories_p = new std::list<const ObjectTypeFactory*>();
}
return *widget_type_factories_p;
}

static const WidgetTypeFactory*
static const ObjectTypeFactory*
lookup_widget_factory (String namespaced_ident)
{
std::list<const WidgetTypeFactory*> &widget_type_factories = widget_type_list();
std::list<const ObjectTypeFactory*> &widget_type_factories = widget_type_list();
namespaced_ident = namespaced_ident;
std::list<const WidgetTypeFactory*>::iterator it;
std::list<const ObjectTypeFactory*>::iterator it;
for (it = widget_type_factories.begin(); it != widget_type_factories.end(); it++)
if ((*it)->qualified_type == namespaced_ident)
return *it;
return NULL;
}

void
WidgetTypeFactory::register_widget_factory (const WidgetTypeFactory &itfactory)
ObjectTypeFactory::register_object_factory (const ObjectTypeFactory &itfactory)
{
std::list<const WidgetTypeFactory*> &widget_type_factories = widget_type_list();
std::list<const ObjectTypeFactory*> &widget_type_factories = widget_type_list();
const char *ident = itfactory.qualified_type.c_str();
const char *base = strrchr (ident, ':');
if (!base || base != ident + 10 - 1 || strncmp (ident, "Rapicorn::", 10) != 0)
fatal ("WidgetTypeFactory registration with invalid/missing domain name: %s", ident);
fatal ("ObjectTypeFactory registration with invalid/missing domain name: %s", ident);
String domain_name;
domain_name.assign (ident, base - ident - 1);
widget_type_factories.push_back (&itfactory);
}

WidgetTypeFactory::WidgetTypeFactory (const char *namespaced_ident) :
ObjectTypeFactory::ObjectTypeFactory (const char *namespaced_ident) :
qualified_type (namespaced_ident)
{}

WidgetTypeFactory::~WidgetTypeFactory ()
ObjectTypeFactory::~ObjectTypeFactory ()
{}

void
WidgetTypeFactory::sanity_check_identifier (const char *namespaced_ident)
ObjectTypeFactory::sanity_check_identifier (const char *namespaced_ident)
{
if (strncmp (namespaced_ident, "Rapicorn::", 10) != 0)
fatal ("WidgetTypeFactory: identifier lacks factory qualification: %s", namespaced_ident);
fatal ("ObjectTypeFactory: identifier lacks factory qualification: %s", namespaced_ident);
}

// == Public factory_context API ==
String
factory_context_name (FactoryContext *fc)
factory_context_name (FactoryContext &fc)
{
assert_return (fc != NULL, "");
const XmlNode &xnode = *fc->xnode;
const XmlNode &xnode = *fc.xnode;
if (check_interface_node (xnode))
return xnode.get_attribute ("id");
else
return xnode.name();
}

String
factory_context_type (FactoryContext *fc)
factory_context_type (FactoryContext &fc)
{
assert_return (fc != NULL, "");
const XmlNode *xnode = fc->xnode;
const XmlNode *xnode = fc.xnode;
if (!check_interface_node (*xnode)) // lookup definition node from child node
{
xnode = lookup_interface_node (xnode->name(), xnode);
@@ -175,10 +173,9 @@ factory_context_type (FactoryContext *fc)
}

UserSource
factory_context_source (FactoryContext *fc)
factory_context_source (FactoryContext &fc)
{
assert_return (fc != NULL, UserSource (""));
const XmlNode *xnode = fc->xnode;
const XmlNode *xnode = fc.xnode;
if (!check_interface_node (*xnode)) // lookup definition node from child node
{
xnode = lookup_interface_node (xnode->name(), xnode);
@@ -208,7 +205,7 @@ factory_context_list_types (StringVector &types, const XmlNode *xnode, const boo
if (!xnode && last->name() == "Rapicorn_Factory")
{
const StringVector &attributes_names = last->list_attributes(), &attributes_values = last->list_values();
const WidgetTypeFactory *widget_factory = NULL;
const ObjectTypeFactory *widget_factory = NULL;
for (size_t i = 0; i < attributes_names.size(); i++)
if (attributes_names[i] == "factory-type" || attributes_names[i] == "factory_type")
{
@@ -227,34 +224,32 @@ factory_context_list_types (StringVector &types, const XmlNode *xnode, const boo
}

static void
factory_context_update_cache (FactoryContext *fc)
factory_context_update_cache (FactoryContext &fc)
{
if (UNLIKELY (!fc->type_tags))
if (UNLIKELY (!fc.type_tags))
{
const XmlNode *xnode = fc->xnode;
fc->type_tags = new StringSeq;
StringVector &types = *fc->type_tags;
const XmlNode *xnode = fc.xnode;
fc.type_tags = new StringSeq;
StringVector &types = *fc.type_tags;
factory_context_list_types (types, xnode, false, false);
fc->type = types.size() ? types[types.size() - 1] : "";
fc.type = types.size() ? types[types.size() - 1] : "";
types.clear();
factory_context_list_types (types, xnode, true, true);
}
}

const StringSeq&
factory_context_tags (FactoryContext *fc)
factory_context_tags (FactoryContext &fc)
{
assert_return (fc != NULL, *(StringSeq*) NULL);
factory_context_update_cache (fc);
return *fc->type_tags;
return *fc.type_tags;
}

String
factory_context_impl_type (FactoryContext *fc)
factory_context_impl_type (FactoryContext &fc)
{
assert_return (fc != NULL, "");
factory_context_update_cache (fc);
return fc->type;
return fc.type;
}

// == Builder ==
@@ -361,7 +356,7 @@ Builder::build_from_factory (const XmlNode *factory_node,
else if (attr_names[i] == "factory_type")
factory_type = attr_values[i];
// lookup widget factory
const WidgetTypeFactory *widget_factory = lookup_widget_factory (factory_type);
const ObjectTypeFactory *widget_factory = lookup_widget_factory (factory_type);
// sanity check factory node
if (factory_node->name() != "Rapicorn_Factory" || !widget_factory ||
attr_names.size() != 2 || factory_node->list_attributes().size() != 2 ||
@@ -378,9 +373,16 @@ Builder::build_from_factory (const XmlNode *factory_node,
fc = new FactoryContext (factory_context_node);
factory_context_map[factory_context_node] = fc;
}
WidgetImplP widget = widget_factory->create_widget (fc);
if (widget)
widget->name (factory_id);
ObjectImplP object = widget_factory->create_object (*fc);
WidgetImplP widget;
if (object)
{
widget = shared_ptr_cast<WidgetImpl> (object);
if (widget)
widget->name (factory_id);
else
critical ("%s: %s yields non-widget: %s", node_location (factory_node), factory_node->name(), object->typeid_name());
}
return widget;
}

@@ -636,7 +638,7 @@ Builder::widget_has_ancestor (const String &widget_identifier, const String &anc
{
initialize_factory_lazily();
const XmlNode *const ancestor_node = lookup_interface_node (ancestor_identifier, NULL); // maybe NULL
const WidgetTypeFactory *const ancestor_itfactory = ancestor_node ? NULL : lookup_widget_factory (ancestor_identifier);
const ObjectTypeFactory *const ancestor_itfactory = ancestor_node ? NULL : lookup_widget_factory (ancestor_identifier);
if (widget_identifier == ancestor_identifier && (ancestor_node || ancestor_itfactory))
return true; // potential fast path
if (!ancestor_node && !ancestor_itfactory)
@@ -656,7 +658,7 @@ Builder::widget_has_ancestor (const String &widget_identifier, const String &anc
if (last && last->name() == "Rapicorn_Factory")
{
const StringVector &attributes_names = last->list_attributes(), &attributes_values = last->list_values();
const WidgetTypeFactory *widget_factory = NULL;
const ObjectTypeFactory *widget_factory = NULL;
for (size_t i = 0; i < attributes_names.size(); i++)
if (attributes_names[i] == "factory-type" || attributes_names[i] == "factory_type")
{
@@ -699,8 +701,7 @@ WidgetImplP
create_ui_child (ContainerImpl &container, const String &widget_identifier, const ArgumentList &arguments, bool autoadd)
{
// figure XML context
FactoryContext *fc = container.factory_context();
assert_return (fc != NULL, NULL);
FactoryContext &fc = container.factory_context();
// create child within parent namespace
//local_namespace_list.push_back (namespace_domain);
WidgetImplP widget = create_ui_widget (widget_identifier, arguments);
@@ -28,23 +28,23 @@ bool check_ui_window (const String &widget_identifier);

typedef map<String,String> VariableMap;

String factory_context_name (FactoryContext *fc);
String factory_context_type (FactoryContext *fc);
const StringSeq& factory_context_tags (FactoryContext *fc);
UserSource factory_context_source (FactoryContext *fc);
String factory_context_impl_type (FactoryContext *fc);
String factory_context_name (FactoryContext &fc);
String factory_context_type (FactoryContext &fc);
const StringSeq& factory_context_tags (FactoryContext &fc);
UserSource factory_context_source (FactoryContext &fc);
String factory_context_impl_type (FactoryContext &fc);

/* --- widget type registration --- */
struct WidgetTypeFactory {
// == Object Type Registration ==
struct ObjectTypeFactory {
const String qualified_type;
RAPICORN_CLASS_NON_COPYABLE (WidgetTypeFactory);
RAPICORN_CLASS_NON_COPYABLE (ObjectTypeFactory);
protected:
static void register_widget_factory (const WidgetTypeFactory &itfactory);
static void register_object_factory (const ObjectTypeFactory &itfactory);
static void sanity_check_identifier (const char *namespaced_ident);
virtual ~WidgetTypeFactory ();
virtual ~ObjectTypeFactory ();
public:
explicit WidgetTypeFactory (const char *namespaced_ident);
virtual WidgetImplP create_widget (FactoryContext *fc) const = 0;
explicit ObjectTypeFactory (const char *namespaced_ident);
virtual ObjectImplP create_object (FactoryContext &fc) const = 0;
virtual void type_name_list (std::vector<const char*> &names) const = 0;
inline String type_name () const { return qualified_type; }
};
@@ -53,18 +53,13 @@ public:

// namespace Rapicorn

/* --- widget factory template --- */
void temp_window_factory_workaround (ObjectIfaceP o);
// == WidgetFactory ==
template<class Type>
class WidgetFactory : Factory::WidgetTypeFactory {
virtual WidgetImplP
create_widget (FactoryContext *fc) const override
class WidgetFactory : Factory::ObjectTypeFactory {
virtual ObjectImplP
create_object (FactoryContext &fc) const override
{
ObjectIfaceP object = (new Type())->temp_factory_workaround();
temp_window_factory_workaround (object);
WidgetImplP widget = shared_ptr_cast<WidgetImpl> (object);
widget->factory_context (fc);
return widget;
return ObjectImpl::make_instance<Type> (fc);
}
virtual void
type_name_list (std::vector<const char*> &names) const override
@@ -79,10 +74,10 @@ class WidgetFactory : Factory::WidgetTypeFactory {
}
public:
explicit WidgetFactory (const char *namespaced_ident) :
WidgetTypeFactory (namespaced_ident)
ObjectTypeFactory (namespaced_ident)
{
sanity_check_identifier (namespaced_ident);
register_widget_factory (*this);
register_object_factory (*this);
}
};

@@ -13,11 +13,11 @@ class AlignmentImpl : public virtual SingleContainerImpl, public virtual Alignme
uint16 bottom_padding_, top_padding_;
virtual int padding () const;
protected:
virtual ~AlignmentImpl () override;
virtual void size_request (Requisition &requisition) override;
virtual void size_allocate (Allocation area, bool changed) override;
public:
explicit AlignmentImpl ();
virtual ~AlignmentImpl () override;
virtual int left_padding () const override;
virtual void left_padding (int c) override;
virtual int right_padding () const override;
@@ -33,21 +33,21 @@ class FillAreaContainerImpl : public virtual SingleContainerImpl, public virtual
String source_;
ImagePainter image_painter_;
protected:
virtual ~FillAreaContainerImpl () override;
virtual void size_request (Requisition &requisition) override;
virtual void size_allocate (Allocation area, bool changed) override;
public:
explicit FillAreaContainerImpl ();
virtual ~FillAreaContainerImpl () override;
virtual void source (const String &uri) override;
virtual String source () const override;
};

class HBoxImpl : public virtual TableLayoutImpl, public virtual HBoxIface {
protected:
virtual ~HBoxImpl () override;
virtual void add_child (WidgetImpl &widget) override;
public:
explicit HBoxImpl ();
virtual ~HBoxImpl () override;
virtual bool homogeneous () const override;
virtual void homogeneous (bool homogeneous_widgets) override;
virtual int spacing () const override;
@@ -56,10 +56,10 @@ public:

class VBoxImpl : public virtual TableLayoutImpl, public virtual VBoxIface {
protected:
virtual ~VBoxImpl () override;
virtual void add_child (WidgetImpl &widget) override;
public:
explicit VBoxImpl ();
virtual ~VBoxImpl () override;
virtual bool homogeneous () const override;
virtual void homogeneous (bool homogeneous_widgets) override;
virtual int spacing () const override;
@@ -3,13 +3,37 @@

namespace Rapicorn {

static __thread FactoryContext *call_stack_ctor_factory_context = NULL;

void
ObjectImpl::ctor_factory_context (FactoryContext *fc)
{
if (fc)
assert_return (call_stack_ctor_factory_context == NULL);
else
assert_return (call_stack_ctor_factory_context != NULL);
call_stack_ctor_factory_context = fc;
}

// Provides factory_context from call stack context during object construction only
FactoryContext&
ObjectImpl::ctor_factory_context ()
{
assert_return (call_stack_ctor_factory_context != NULL, *(FactoryContext*) NULL);
return *call_stack_ctor_factory_context;
}

ObjectImpl::ObjectImpl () :
sig_changed (slot (*this, &ObjectImpl::do_changed))
{}

ObjectImpl::~ObjectImpl()
{}

void
ObjectImpl::constructed ()
{}

void
ObjectImpl::dispose ()
{}

0 comments on commit 92fa5a8

Please sign in to comment.
You can’t perform that action at this time.