Canvas: Ensure all element types are initialized before first usage.

If setting properties on a group a check is performed if
this property exists on any possible child element, and
only if this is the case the property is stored in the
groups style.

Previously elements have been only initialized during
their first usage, leading to ignored styles if they
have been set on a parent element before instantiating
an instance of the actual element type.
This commit is contained in:
Thomas Geymayer 2013-07-20 15:45:02 +02:00
parent fc75b0bd21
commit b236821661
12 changed files with 125 additions and 66 deletions

View File

@ -523,6 +523,8 @@ namespace canvas
_style( parent_style ),
_drawable( 0 )
{
staticInit();
SG_LOG
(
SG_GL,
@ -530,11 +532,6 @@ namespace canvas
"New canvas element " << node->getPath()
);
if( !isInit<Element>() )
{
addStyle("clip", "", &Element::setClip, false);
}
// Ensure elements are drawn in order they appear in the element tree
_transform->getOrCreateStateSet()
->setRenderBinDetails
@ -545,6 +542,15 @@ namespace canvas
);
}
//----------------------------------------------------------------------------
void Element::staticInit()
{
if( isInit<Element>() )
return;
addStyle("clip", "", &Element::setClip, false);
}
//----------------------------------------------------------------------------
bool Element::isStyleEmpty(const SGPropertyNode* child) const
{

View File

@ -197,6 +197,8 @@ namespace canvas
typedef std::map<std::string, StyleInfo> StyleSetters;
static StyleSetters _style_setters;
static void staticInit();
Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
@ -210,7 +212,7 @@ namespace canvas
* @tparam Derived (Derived) class type
*/
template<class Derived>
bool isInit() const
static bool isInit()
{
static bool is_init = false;
if( is_init )
@ -239,6 +241,7 @@ namespace canvas
typename T2,
class Derived
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -282,6 +285,7 @@ namespace canvas
typename T,
class Derived
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -295,6 +299,7 @@ namespace canvas
typename T,
class Derived
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -315,6 +320,7 @@ namespace canvas
typename T2,
class Derived
>
static
StyleSetterFunc
addStyle( const std::string& name,
const std::string& type,
@ -333,6 +339,7 @@ namespace canvas
template<
class Derived
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -354,6 +361,7 @@ namespace canvas
class Other,
class OtherRef
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -377,6 +385,7 @@ namespace canvas
class Other,
class OtherRef
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -400,6 +409,7 @@ namespace canvas
class Other,
class OtherRef
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -421,6 +431,7 @@ namespace canvas
class Other,
class OtherRef
>
static
StyleSetter
addStyle( const std::string& name,
const std::string& type,
@ -439,6 +450,7 @@ namespace canvas
}
template<typename T, class Derived, class Other, class OtherRef>
static
boost::function<void (Derived&, T)>
bindOther( void (Other::*setter)(T), OtherRef Derived::*instance_ref )
{
@ -446,6 +458,7 @@ namespace canvas
}
template<typename T, class Derived, class Other, class OtherRef>
static
boost::function<void (Derived&, T)>
bindOther( const boost::function<void (Other&, T)>& setter,
OtherRef Derived::*instance_ref )
@ -463,6 +476,7 @@ namespace canvas
}
template<typename T1, typename T2, class Derived>
static
StyleSetterFuncUnchecked
bindStyleSetter( const std::string& name,
const boost::function<void (Derived&, T2)>& setter )

View File

@ -38,6 +38,7 @@ namespace canvas
template<typename ElementType>
void add(ElementFactories& factories)
{
ElementType::staticInit();
factories[ElementType::TYPE_NAME] = &Element::create<ElementType>;
}
@ -52,6 +53,19 @@ namespace canvas
"canvas::Group::" << member_name << ": Group has expired." );
}
//----------------------------------------------------------------------------
void Group::staticInit()
{
if( isInit<Group>() )
return;
add<Group>(_child_factories);
add<Image>(_child_factories);
add<Map >(_child_factories);
add<Path >(_child_factories);
add<Text >(_child_factories);
}
//----------------------------------------------------------------------------
Group::Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
@ -59,14 +73,7 @@ namespace canvas
Element* parent ):
Element(canvas, node, parent_style, parent)
{
if( !isInit<Group>() )
{
add<Group>(_child_factories);
add<Image>(_child_factories);
add<Map >(_child_factories);
add<Path >(_child_factories);
add<Text >(_child_factories);
}
staticInit();
}
//----------------------------------------------------------------------------

View File

@ -35,6 +35,7 @@ namespace canvas
{
public:
static const std::string TYPE_NAME;
static void staticInit();
typedef std::list< std::pair< const SGPropertyNode*,
ElementPtr

View File

@ -89,6 +89,18 @@ namespace canvas
//----------------------------------------------------------------------------
const std::string Image::TYPE_NAME = "image";
//----------------------------------------------------------------------------
void Image::staticInit()
{
if( isInit<Image>() )
return;
addStyle("fill", "color", &Image::setFill);
addStyle("slice", "", &Image::setSlice);
addStyle("slice-width", "", &Image::setSliceWidth);
addStyle("outset", "", &Image::setOutset);
}
//----------------------------------------------------------------------------
Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
@ -100,6 +112,8 @@ namespace canvas
_src_rect(0,0),
_region(0,0)
{
staticInit();
_geom = new osg::Geometry;
_geom->setUseDisplayList(false);
@ -128,16 +142,7 @@ namespace canvas
setDrawable(_geom);
if( !isInit<Image>() )
{
addStyle("fill", "color", &Image::setFill);
addStyle("slice", "", &Image::setSlice);
addStyle("slice-width", "", &Image::setSliceWidth);
addStyle("outset", "", &Image::setOutset);
}
setFill("#ffffff"); // TODO how should we handle default values?
setupStyle();
}

View File

@ -35,6 +35,7 @@ namespace canvas
{
public:
static const std::string TYPE_NAME;
static void staticInit();
/**
* @param node Property node containing settings for this image:

View File

@ -46,6 +46,17 @@ namespace canvas
const std::string GEO = "-geo";
const std::string Map::TYPE_NAME = "map";
//----------------------------------------------------------------------------
void Map::staticInit()
{
Group::staticInit();
if( isInit<Map>() )
return;
// Do some initialization if needed...
}
//----------------------------------------------------------------------------
Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
@ -56,7 +67,7 @@ namespace canvas
_projection(new SansonFlamsteedProjection),
_projection_dirty(true)
{
staticInit();
}
//----------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@ namespace canvas
{
public:
static const std::string TYPE_NAME;
static void staticInit();
Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,

View File

@ -472,6 +472,22 @@ namespace canvas
//----------------------------------------------------------------------------
const std::string Path::TYPE_NAME = "path";
//----------------------------------------------------------------------------
void Path::staticInit()
{
if( isInit<Path>() )
return;
PathDrawableRef Path::*path = &Path::_path;
addStyle("fill", "color", &PathDrawable::setFill, path);
addStyle("fill-rule", "", &PathDrawable::setFillRule, path);
addStyle("stroke", "color", &PathDrawable::setStroke, path);
addStyle("stroke-width", "numeric", &PathDrawable::setStrokeWidth, path);
addStyle("stroke-dasharray", "", &PathDrawable::setStrokeDashArray, path);
addStyle("stroke-linecap", "", &PathDrawable::setStrokeLinecap, path);
}
//----------------------------------------------------------------------------
Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
@ -480,20 +496,9 @@ namespace canvas
Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) )
{
staticInit();
setDrawable(_path);
if( !isInit<Path>() )
{
PathDrawableRef Path::*path = &Path::_path;
addStyle("fill", "color", &PathDrawable::setFill, path);
addStyle("fill-rule", "", &PathDrawable::setFillRule, path);
addStyle("stroke", "color", &PathDrawable::setStroke, path);
addStyle("stroke-width", "numeric", &PathDrawable::setStrokeWidth, path);
addStyle("stroke-dasharray", "", &PathDrawable::setStrokeDashArray, path);
addStyle("stroke-linecap", "", &PathDrawable::setStrokeLinecap, path);
}
setupStyle();
}

View File

@ -31,6 +31,7 @@ namespace canvas
{
public:
static const std::string TYPE_NAME;
static void staticInit();
Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,

View File

@ -261,6 +261,39 @@ namespace canvas
//----------------------------------------------------------------------------
const std::string Text::TYPE_NAME = "text";
//----------------------------------------------------------------------------
void Text::staticInit()
{
if( isInit<Text>() )
return;
osg::ref_ptr<TextOSG> Text::*text = &Text::_text;
addStyle("fill", "color", &TextOSG::setFill, text);
addStyle("background", "color", &TextOSG::setBackgroundColor, text);
addStyle("character-size",
"numeric",
static_cast<
void (TextOSG::*)(float)
> (&TextOSG::setCharacterSize),
text);
addStyle("character-aspect-ratio",
"numeric",
&TextOSG::setCharacterAspect, text);
addStyle("line-height", "numeric", &TextOSG::setLineHeight, text);
addStyle("font-resolution", "numeric", &TextOSG::setFontResolution, text);
addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text);
// TEXT = 1 default
// BOUNDINGBOX = 2
// FILLEDBOUNDINGBOX = 4
// ALIGNMENT = 8
addStyle<int>("draw-mode", "", &TextOSG::setDrawMode, text);
addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text);
addStyle("font", "", &Text::setFont);
addStyle("alignment", "", &Text::setAlignment);
addStyle("text", "", &Text::setText, false);
}
//----------------------------------------------------------------------------
Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
@ -269,40 +302,13 @@ namespace canvas
Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) )
{
staticInit();
setDrawable(_text);
_text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
_text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION);
_text->setRotation(osg::Quat(osg::PI, osg::X_AXIS));
if( !isInit<Text>() )
{
osg::ref_ptr<TextOSG> Text::*text = &Text::_text;
addStyle("fill", "color", &TextOSG::setFill, text);
addStyle("background", "color", &TextOSG::setBackgroundColor, text);
addStyle("character-size",
"numeric",
static_cast<
void (TextOSG::*)(float)
> (&TextOSG::setCharacterSize),
text);
addStyle("character-aspect-ratio",
"numeric",
&TextOSG::setCharacterAspect, text);
addStyle("line-height", "numeric", &TextOSG::setLineHeight, text);
addStyle("font-resolution", "numeric", &TextOSG::setFontResolution, text);
addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text);
// TEXT = 1 default
// BOUNDINGBOX = 2
// FILLEDBOUNDINGBOX = 4
// ALIGNMENT = 8
addStyle<int>("draw-mode", "", &TextOSG::setDrawMode, text);
addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text);
addStyle("font", "", &Text::setFont);
addStyle("alignment", "", &Text::setAlignment);
addStyle("text", "", &Text::setText, false);
}
setupStyle();
}

View File

@ -34,6 +34,7 @@ namespace canvas
{
public:
static const std::string TYPE_NAME;
static void staticInit();
Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,