This page is obsolete:
Attributes have been added to wallaroo.
Currently (v. 0.5 - april 2014), the main limit of wallaroo is the maximum number of constructor parameters a managed class can have (i.e. two). Besides, a class defined in a dynamic library must have a constructor without parameters.
Removing this limit could be the last activity before finally bring the release number to 1.0
This wiki page contains some notes about this topic.
Currently, wallaroo only manages classes (part
s) having constructors with 0, 1 or 2 parameters. Besides, the limit for classes defined in shared libraries is stricter: they must have a default constructor.
This limit is due to the following problems:
void
case; string
) and the type of the two constructor parameters (template parameters, possibly void
). In a configuration file you need to specify all these three piece of information. No problem for the class name (it's a string!), but the parameters must be converted from strings to types, providing all the possible permutations (see file ptreebasedcfg.h
). Incrementing the parameters number would produce an exponential increment of the combinations. The current code has also some advantages:
Catalog::Create
directly with the parameters of the object you want to create (no extra verbosity) Wallaroo needs a mechanism to pass an arbitrary number of parameters when constructing an object (a part
in wallaroo parlance). The solution should have the following properties:
boost
libraries in those cases where now are not needed Here are explained a list of candidate solutions.
We can pass a table of named parameters to the ctor (e.g.: std::map< std::string, boost::any >
). This means:
boost::any
everywhere), unless we develop our own version of any
. To simplify the usage, we could provide a ParameterSet
class that incapsulate the map
, hiding the use of any
:
E.g. (class definition)
class Foo : public Part { public: Foo( const ParameterSet& pars ); ... private: std::string color; int number; ... }; WALLAROO_REGISTER( Foo ) // register this class Foo::Foo( const ParameterSet& pars ) : color( pars[ "color" ] ), number( pars[ "number"] ) { }
E.g. (usage)
Catalog catalog; ParameterSet pars; pars[ "color" ] = "red"; pars[ "number" ] = 42; catalog.Create( "foo", "Foo", pars );
When using a configuration file (xml, json), we have two options:
any
object) We can use a mechanism similar to wallaroo::Collaborator
to add const
attributes to the class.
This way, an object would be created without parameters, then its const attributes filled using an injection mechanism imilar to the one used for dependencies.
E.g. (class definition)
class Foo : public Part { public: Foo(); virtual ~Foo(); ... private: Collaborator< Bar > bar; Attribute< std::string > color; Attribute< int > number; }; WALLAROO_REGISTER( Foo ) // register this class Foo::Foo() : bar( "b", RegistrationToken() ), color( "color", RegistrationToken() ), number( "number", RegistrationToken() ) { }
E.g. (usage)
Catalog catalog; catalog.Create( "foo", "Foo" ); catalog.Create( "bar", "Bar" ); // option #1 catalog[ "foo" ][ "color" ] = "red"; catalog[ "foo" ][ "number" ] = 42; wallaroo_within( catalog ) { use( "bar" ).as( "b" ).of( "foo" ); // option #2 set( "color" ).of( "foo" ).to( "red" ); set( "number" ).of( "foo" ).to( 42 ); } // check if all collaborators are wired assert( catalog.IsWiringOk() ); // check if all attributes are set assert( catalog.AreAttributesOk() ); // calls the method Init of each parts // maybe it would be better to call IsWiringOk // and AreAttributesOk inside Catalog::Init() ? catalog.Init();
Is this feasible in the first place?
Please note that in traditional programming the constructor parameters are possibly used inside the body of the constructor; with this approach, instead, the attributes are not yet set during the parts constructor execution. A possible workaround for this issue is to provide some kind of Part::Init
method where doing the actual part setup work that require the attributes. A Catalog::Init
method could call Part::Init
for each part contained.
When using a configuration file (xml, json), we still have two options:
set( "attribute_name" ).of( "part_name" ).to( object );
); to
can take a string and the conversion to the right type can be operated inside the Attribute<T>
class (that knows the actual type - T). Suggestions are welcome :-)
Wiki: Attributes
Wiki: TableOfContents
View and moderate all "wiki Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Wiki"
Originally posted by: fabien.c...@gmail.com
Good start :)
Remark 1:
If you dont want a dependancy to boost, may be you could use a minimal "any" class like that : http://stackoverflow.com/questions/4988939/how-do-boostvariant-and-boostany-work
Remark 2:
The other solution could be to wrap all basic types (int, long, double, string, etc.) as a Plug itself, or keeping the Attribute concept. So instead of
use( "bar" ).as( "b" ).of( "foo" );
one could write :
use( "red" ).as( "color" ).of( "foo" ); or use( 42 ).as( "number" ).of( "foo" );
This implied to modify a bit the use func.
I am wondering if there is a good reason to adopt the pair Attribute/set...of...to instead of extending the Plug concept ...
View and moderate all "wiki Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Wiki"
Originally posted by: fabien.c...@gmail.com
last thing : I dont understand the Device::Init usage ... Could you be more specific?
View and moderate all "wiki Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Wiki"
Originally posted by: fabien.c...@gmail.com
"I am wondering if there is a good reason to adopt the pair Attribute/set...of...to instead of extending the Plug concept ... ".
I really think the Plug and Attribute concepts are different : Attribute belongs to the instance while Plug belongs to the usage of the instance.
View and moderate all "wiki Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Wiki"
Originally posted by: daniele....@gmail.com
I expanded a bit the explanation of Device::Init. Hope it's more clear, now.
If we go for solution #1 I'll develop a wallaroo version of any, thanks.
Yes: I guess Plug and Attribute are different concepts... I really wouldn't like to create confusion (read: bugs :-) in the mind of the user. Anyway: the syntax is important but now I'd prefer to focus on the choice of the best solution, whether they're feasible, whether there is any problem in the implementation (e.g. with shared libraries usage) and so on...
View and moderate all "wiki Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Wiki"
Originally posted by: fabien.c...@gmail.com
1- You are right about the Init function.
2- I am playing right now with wallaroo and I dont have enough perspective for #1 or #2 solution.
The input ParameterSet? as argument is good because it is very easy to manipulate and changing its content. This can be also a trap : weak-typing is the beginning of the end ...
Attribute injection is heavy but the AtttributeOk?() check is a good structural check. I have a little preference for this one but you're the leader, your call :)
Thanks anyway