Hi,
I have a case where it would be useful for me to be able to reuse as
much from the property infrastructure as possible, but not everything.
In short:
I would like to be able to read data from a file in an operation of
component A. That data is already used to set properties of another
component B, so it is already available for free in the cpf format.
Note that, for component A, the data is not to be considered as a
property, but rather as private data not to be exposed to the outer
world.
As a workaround, I now just add the same properties to A and work with
them as properties. This means I can reuse the data file, don't have
to worry about parsing, and I can reuse a simple
marshalling->loadProperties() to load the data from the file.
However, that also means that any peer component could theoretically
modify those values, which is what i don't want.
Is there some primitive available in RTT that better fits to my
problem than using properties?
Klaas
PrivateAttribute?
On Friday 05 February 2010 16:50:03 Klaas Gadeyne wrote:
> Hi,
>
> I have a case where it would be useful for me to be able to reuse as
> much from the property infrastructure as possible, but not everything.
> In short:
>
> I would like to be able to read data from a file in an operation of
> component A. That data is already used to set properties of another
> component B, so it is already available for free in the cpf format.
> Note that, for component A, the data is not to be considered as a
> property, but rather as private data not to be exposed to the outer
> world.
> As a workaround, I now just add the same properties to A and work with
> them as properties. This means I can reuse the data file, don't have
> to worry about parsing, and I can reuse a simple
> marshalling->loadProperties() to load the data from the file.
> However, that also means that any peer component could theoretically
> modify those values, which is what i don't want.
>
> Is there some primitive available in RTT that better fits to my
> problem than using properties?
You could use the CPF marshaller classes directly, which saves you from adding
the property bag to your taskcontext, as a consequence, they remain hidden.
To elaborate on this further...
The eternal discussion of public vs private is about the tools only. We can't
make anything *really* private. The C++ compiler doesn't either, remember. The
best we can do is 'mark' it as private and have the tools refuse to display
them/look them up in 'certain cases'. This would only allow abuse when not
using the tools that take these cases into account.
For example, you wouldn't want the TaskBrowser to refuse to display 'private'
variables, would you ? And wouldn't you wish to tweak such a variable during
debugging ? And how is the TaskBrowserComponent different from any other
component ? It isn't. It obeys the exact same rules.
The closest we can get is to:
1. make scripting respect privateness, meaning, accessing private foo of own
component is ok, private foo of peer component is not
2. Not export private foo's to CORBA interface or similar (confines private to
own process) -> this would imply that only in-process taskbrowsers would be
able to see them and could make debugging remote processes harder.
In 2.0, stuff gets grouped into 'services'. You could define a service named
"private" and harbour the private stuff in there. You could then at the end of
your configureHook, delete that interface, such that no-one can access it
anymore afterwards. The current users don't have a problem because of shared
pionters in the background.
In my opinion, it's not worth it, but a reasonably sized patch could have a
chance to convince me, as always.
Peter
PrivateAttribute?
On Mon, Feb 8, 2010 at 4:30 PM, Peter Soetens <peter [dot] soetens [..] ...> wrote:
> On Friday 05 February 2010 16:50:03 Klaas Gadeyne wrote:
>> Hi,
>>
>> I have a case where it would be useful for me to be able to reuse as
>> much from the property infrastructure as possible, but not everything.
>> In short:
>>
>> I would like to be able to read data from a file in an operation of
>> component A. That data is already used to set properties of another
>> component B, so it is already available for free in the cpf format.
>> Note that, for component A, the data is not to be considered as a
>> property, but rather as private data not to be exposed to the outer
>> world.
>> As a workaround, I now just add the same properties to A and work with
>> them as properties. This means I can reuse the data file, don't have
>> to worry about parsing, and I can reuse a simple
>> marshalling->loadProperties() to load the data from the file.
>> However, that also means that any peer component could theoretically
>> modify those values, which is what i don't want.
>>
>> Is there some primitive available in RTT that better fits to my
>> problem than using properties?
>
> You could use the CPF marshaller classes directly, which saves you from adding
> the property bag to your taskcontext, as a consequence, they remain hidden.
>
> To elaborate on this further...
>
> The eternal discussion of public vs private is about the tools only. We can't
> make anything *really* private. The C++ compiler doesn't either, remember. The
> best we can do is 'mark' it as private and have the tools refuse to display
> them/look them up in 'certain cases'. This would only allow abuse when not
> using the tools that take these cases into account.
Strictly speaking, maybe yes, but look at the following cut and paste
from reality...
In this case, IMHO, it's _not_ just about the tools, it's also about
semantics and code readability.
It's about me having to explain people having to use different orocos
primitives depending on x, y, and z.
Consider the comments in this self-explaining real-life example (just
copied from "production code"). [*]
<quote>
class ValidatorComponent
: public TaskContext
{
[snip]
protected:
/* Make a distinction between
* - events that are actually "commands" from other components for this
* component, but should be events since otherwise we can't react on them
* in our state machines and
* - events which are Events that are (or better: should be) fired _by_
* this component and to which other components can react.
*/
/* The commands */
Event<void(void)> startTestEvent;
Event<void(void)> stopTestEvent;
/* The real events to be used by this component's SM */
/* Shouldn't be fired by another component, but hey */
Event<void(void)> fatalErrorEvent;
Event<void(int)> operationDoneEvent;
Event<void(string)> setSDTypeEvent;
Event<void(string, string)> sendMessageEvent;
Event<void(void)> physicalErrorEvent;
Event<void(void)> recoverEvent;
/* These are not real-properties and shouldn't be exposed to other
components. It's merely a
* workaround/shortcut to get the data necessary for the
validation from the properties of the
* excitator.
*/
Property<std::string> SDType;
Property<double> stiffness;
Property<double> damping;
Property<double> amplitude;
Property<double> bias;
/* Private Methods put in public API so we can use them in StateMachines */
Method<void(void)> writeLogHeadersMethod;
Method<bool(void)> closeLogFilesMethod;
Method<void(double)> validateMethod;
<quote>
> For example, you wouldn't want the TaskBrowser to refuse to display 'private'
> variables, would you ? And wouldn't you wish to tweak such a variable during
> debugging ? And how is the TaskBrowserComponent different from any other
> component ? It isn't. It obeys the exact same rules.
I don't know. The Taskbrowser can (could?) Enter/Leave another
component. So debugging-wise it should see exactly what other
components see when it is not _in_ the other component.
> The closest we can get is to:
1. make scripting respect privateness, meaning, accessing private foo of own
> component is ok, private foo of peer component is not
makes sense
> 2. Not export private foo's to CORBA interface or similar (confines private to
> own process) -> this would imply that only in-process taskbrowsers would be
> able to see them and could make debugging remote processes harder.
> In 2.0, stuff gets grouped into 'services'. You could define a service named
> "private" and harbour the private stuff in there. You could then at the end of
> your configureHook, delete that interface, such that no-one can access it
> anymore afterwards. The current users don't have a problem because of shared
> pionters in the background.
I don't understand this very well, but it seems a little ugly anyway :-)
Klaas
[*] I'm happy I'm not a consultant having to explain this ;-)))
PrivateAttribute?
On Wednesday 10 February 2010 14:34:47 Klaas Gadeyne wrote:
> On Mon, Feb 8, 2010 at 4:30 PM, Peter Soetens <peter [dot] soetens [..] ...>
wrote:
> > On Friday 05 February 2010 16:50:03 Klaas Gadeyne wrote:
> >> Hi,
> >>
> >> I have a case where it would be useful for me to be able to reuse as
> >> much from the property infrastructure as possible, but not everything.
> >> In short:
> >>
> >> I would like to be able to read data from a file in an operation of
> >> component A. That data is already used to set properties of another
> >> component B, so it is already available for free in the cpf format.
> >> Note that, for component A, the data is not to be considered as a
> >> property, but rather as private data not to be exposed to the outer
> >> world.
> >> As a workaround, I now just add the same properties to A and work with
> >> them as properties. This means I can reuse the data file, don't have
> >> to worry about parsing, and I can reuse a simple
> >> marshalling->loadProperties() to load the data from the file.
> >> However, that also means that any peer component could theoretically
> >> modify those values, which is what i don't want.
> >>
> >> Is there some primitive available in RTT that better fits to my
> >> problem than using properties?
> >
> > You could use the CPF marshaller classes directly, which saves you from
> > adding the property bag to your taskcontext, as a consequence, they
> > remain hidden.
> >
> > To elaborate on this further...
> >
> > The eternal discussion of public vs private is about the tools only. We
> > can't make anything *really* private. The C++ compiler doesn't either,
> > remember. The best we can do is 'mark' it as private and have the tools
> > refuse to display them/look them up in 'certain cases'. This would only
> > allow abuse when not using the tools that take these cases into account.
>
> Strictly speaking, maybe yes, but look at the following cut and paste
> from reality...
Good. Real-world code speaks.
> In this case, IMHO, it's _not_ just about the tools, it's also about
> semantics and code readability.
> It's about me having to explain people having to use different orocos
> primitives depending on x, y, and z.
Please show an example of how you would like to express in code and
documentation that a certain pimitive is private.
>
> Consider the comments in this self-explaining real-life example (just
> copied from "production code"). [*]
>
> <quote>
> class ValidatorComponent
>
> : public TaskContext
>
> {
> [snip]
> protected:
> /* Make a distinction between
> * - events that are actually "commands" from other components for this
> * component, but should be events since otherwise we can't react on
> them * in our state machines and
> * - events which are Events that are (or better: should be) fired _by_
> * this component and to which other components can react.
> */
> /* The commands */
> Event<void(void)> startTestEvent;
> Event<void(void)> stopTestEvent;
>
> /* The real events to be used by this component's SM */
> /* Shouldn't be fired by another component, but hey */
> Event<void(void)> fatalErrorEvent;
> Event<void(int)> operationDoneEvent;
> Event<void(string)> setSDTypeEvent;
> Event<void(string, string)> sendMessageEvent;
> Event<void(void)> physicalErrorEvent;
> Event<void(void)> recoverEvent;
These are still an open issue... in another thread where I'm waiting your
answer.
For the commands part, state machines will want to attach callback handlers to
operations in the component interface, this is wip.
For the real event part, we're even further away from what you have. I also
started a thread about this (events turned into output ports), without a
conclusion yet.
>
> /* These are not real-properties and shouldn't be exposed to other
> components. It's merely a
> * workaround/shortcut to get the data necessary for the
> validation from the properties of the
> * excitator.
> */
> Property<std::string> SDType;
> Property<double> stiffness;
> Property<double> damping;
> Property<double> amplitude;
> Property<double> bias;
Your workaround probably needed to be solved at the system level instead of at
the component level. You probably added too much coupling here (guessing).
>
> /* Private Methods put in public API so we can use them in
> StateMachines */ Method<void(void)> writeLogHeadersMethod;
> Method<bool(void)> closeLogFilesMethod;
> Method<void(double)> validateMethod;
I see your point. In 2.0, we group property/operation interfaces in services.
Expressing that a group of primitives belongs to service named "private" is
doing what you require. So the SM would call 'private.validateMethod(x)' or
read 'private.bias'. Calling 'ComponentB.private.bias' would then clearly flag
as a violation to the reader, but not to the RTT. It's easy and tempting to
have RTT warn on the use of a 'private' service outside a component, but I'm
not going to write it. Anyone wanting this will have to propose a patch.
Data Ports are not a part of the service interface, but of the component's
data flow interface, which causes them to be always 'top level public'. This
complicates things when you are converting your private Event to OutputPort in
2.0. It seems 'private' Events will map to operations in a private service (to
which the local SM can react) and public Events will map to output ports in
the data flow interface, to which any SM can react.
It's likely that some of this stuff will be for 2.2.
Peter
PrivateAttribute?
On Mon, Feb 22, 2010 at 10:35 AM, Peter Soetens <peter [dot] soetens [..] ...> wrote:
> On Wednesday 10 February 2010 14:34:47 Klaas Gadeyne wrote:
>> On Mon, Feb 8, 2010 at 4:30 PM, Peter Soetens <peter [dot] soetens [..] ...>
> wrote:
>> > On Friday 05 February 2010 16:50:03 Klaas Gadeyne wrote:
[...]
>> Strictly speaking, maybe yes, but look at the following cut and paste
>> from reality...
>
> Good. Real-world code speaks.
>
>> In this case, IMHO, it's _not_ just about the tools, it's also about
>> semantics and code readability.
>> It's about me having to explain people having to use different orocos
>> primitives depending on x, y, and z.
>
> Please show an example of how you would like to express in code and
> documentation that a certain pimitive is private.
I'm not convinced that this discussion is solely about the distinction
private/public.
For instance, the example below of the events shows that sometimes,
you have to use a command, and sometimes you have to use an event,
depending on wether your components implementation uses scripting or
not. These kind of things shouldn't be visible from the outside of
the component.
So when you want to achieve "Command like behaviour", you sometimes
have to use a command, and sometimes an event.
>> Consider the comments in this self-explaining real-life example (just
>> copied from "production code"). [*]
>>
>> <quote>
>> class ValidatorComponent
>>
>> : public TaskContext
>>
>> {
>> [snip]
>> protected:
>> /* Make a distinction between
>> * - events that are actually "commands" from other components for this
>> * component, but should be events since otherwise we can't react on
>> them * in our state machines and
>> * - events which are Events that are (or better: should be) fired _by_
>> * this component and to which other components can react.
>> */
>> /* The commands */
>> Event<void(void)> startTestEvent;
>> Event<void(void)> stopTestEvent;
>>
>> /* The real events to be used by this component's SM */
>> /* Shouldn't be fired by another component, but hey */
>> Event<void(void)> fatalErrorEvent;
>> Event<void(int)> operationDoneEvent;
>> Event<void(string)> setSDTypeEvent;
>> Event<void(string, string)> sendMessageEvent;
>> Event<void(void)> physicalErrorEvent;
>> Event<void(void)> recoverEvent;
>
>
> These are still an open issue... in another thread where I'm waiting your
> answer.
Can you point me to that thread?
> For the commands part, state machines will want to attach callback handlers to
> operations in the component interface, this is wip.
Great!
> For the real event part, we're even further away from what you have.
I have nothing :-)
And to be clear: the above code snippet comes from code that works. However,
My main concerns are 1/ the fact that it's _very_ hard to explain
these kinds of things to beginner users and 2/ I don't like the fact
that I sometimes have to change the API of my component, due to a
change in implementation (going from c++ to scripting fi.).
> I also
> started a thread about this (events turned into output ports), without a
> conclusion yet.
>
>>
>> /* These are not real-properties and shouldn't be exposed to other
>> components. It's merely a
>> * workaround/shortcut to get the data necessary for the
>> validation from the properties of the
>> * excitator.
>> */
>> Property<std::string> SDType;
>> Property<double> stiffness;
>> Property<double> damping;
>> Property<double> amplitude;
>> Property<double> bias;
>
> Your workaround probably needed to be solved at the system level instead of at
> the component level. You probably added too much coupling here (guessing).
Dunno, my first thought would even be that I didn't add enough coupling...
But due to confidentiality reasons it's a bit hard to elaborate on this.
>>
>> /* Private Methods put in public API so we can use them in
>> StateMachines */ Method<void(void)> writeLogHeadersMethod;
>> Method<bool(void)> closeLogFilesMethod;
>> Method<void(double)> validateMethod;
>
> I see your point. In 2.0, we group property/operation interfaces in services.
> Expressing that a group of primitives belongs to service named "private" is
> doing what you require. So the SM would call 'private.validateMethod(x)' or
> read 'private.bias'. Calling 'ComponentB.private.bias' would then clearly flag
> as a violation to the reader, but not to the RTT. It's easy and tempting to
> have RTT warn on the use of a 'private' service outside a component, but I'm
> not going to write it. Anyone wanting this will have to propose a patch.
Makes sense and seems feasible (you don't mention wether you will
accept the patch though :-)
The concept is very similar to plain c++ private vs. public. In this
case, I consider a program script to be part of the component's
implementation, and hence able to check private stuff.
> Data Ports are not a part of the service interface, but of the component's
> data flow interface, which causes them to be always 'top level public'. This
> complicates things when you are converting your private Event to OutputPort in
> 2.0. It seems 'private' Events will map to operations in a private service (to
> which the local SM can react) and public Events will map to output ports in
> the data flow interface, to which any SM can react.
Get's too complicated for me...
> It's likely that some of this stuff will be for 2.2.
I'd say "Release it when it's ready" :-)
Best regards,
Klaas
PrivateAttribute?
On Feb 5, 2010, at 10:50 , Klaas Gadeyne wrote:
> Hi,
>
> I have a case where it would be useful for me to be able to reuse as
> much from the property infrastructure as possible, but not everything.
> In short:
>
> I would like to be able to read data from a file in an operation of
> component A. That data is already used to set properties of another
> component B, so it is already available for free in the cpf format.
> Note that, for component A, the data is not to be considered as a
> property, but rather as private data not to be exposed to the outer
> world.
> As a workaround, I now just add the same properties to A and work with
> them as properties. This means I can reuse the data file, don't have
> to worry about parsing, and I can reuse a simple
> marshalling->loadProperties() to load the data from the file.
> However, that also means that any peer component could theoretically
> modify those values, which is what i don't want.
>
> Is there some primitive available in RTT that better fits to my
> problem than using properties?
A similar concept might be useful in some of my projects too, where we have events, etc, that are private to a component's state machine (or program scripts). They have to go into the interface so that the state machine can use them, however, this makes them available to other components.
But ... I also can't even begin to imagine how much work it might take to provide this ... it is not small, I would bet. :-)
Stephen