EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: data access structures, strings
From: "Jeff Hill" <[email protected]>
To: "'Kay-Uwe Kasemir'" <[email protected]>, <[email protected]>
Date: Mon, 26 Sep 2005 12:12:39 -0600
Kay,

1) In your example you know at compile time that you want to extract the
red, green, and blue properties out of some unknown PropertyCatalog. Your
example is therefore unnecessarily complicated. Here is a simplified
approach. We will use the name catalogX for the unknown PropertCatalog to be
extracted from. We will use the name MyColor for the class that knows it
wants RGB at compile time.

In this situation you have control over the content of MyColor and no
control over the content of catalogX. Since you have control over MyColor
you can access it in any way MyColor sees fit - with blinding speed.

MyColor mc;
mc.set ( catalogX );

extern PropertyId & colorRed;
extern PropertyId & colorGreen;
extern PropertyId & colorBlue;

struct MyColor 
{
public:
    void set ( const & PropertyCatalog );
private:
    int r, g, b;
    template < class VIEWER >
    static void traverse ( VIEWER & );
};

MyColor :: set ( const PropertyCatalog & incoming ) 
{
    ClassCatalog 
        < MyColor, PropertyManipulator, traverse > 
		manipulator ( *this );
    manipulator = incoming;
}

template < class VIEWER >
inline void MyColor :: traverse ( VIEWER & viewer )
{
    viewer.reveal ( colorRed, & MyColor::r );
    viewer.reveal ( colorGreen, & MyColor::g );
    viewer.reveal ( colorBlue, & MyColor::b );
}

Note that there is no need for initialization flags above because the
ClassCatalog guarantees that when making assignments that *all* properties
on the destination are set.

Note that there is no implementation of find above (that's because the
default find now implements find with traverse). You can still optimize find
as you see fit by overriding the base find.

2) If you want to have "MyColor->find("color")->find("red")->toDouble()"
that's easy to. We could do this writing only a very small amount of code on
top of DataAccess reveal interfaces. This code can be written once, placed
in a library, and reused for any type of property, and is *not* specific to
red green, and blue colors. I noticed in your example that you are writing
many reveal functions. There is no need for this with C++ templates. C++
templates are great for situations where the algorithm Is the same, but the
data type varies. I can show you how to automate this if you are interested
(DA internally makes heavy use of this technique).

Personally, the
getDouble()/getFloat/getInt/getUnsigned/getTime/getString/... type of
interface makes me nauseous. It looks from my perspective exactly like the
negative aspects of the GDD interface design. You have to play that game
"are you an animal, vegetable, or mineral" with the data. All of the design
guides recommend calling an application specific virtual function that is
implemented for all of the different data types (using a template of
course). Many C++ tutorials use the example virtual function
"displayYourSelf ()".

3) Here is a better design compared to
MyColor->find("color")->find("red")->toDouble()" IMHO. Presumably you are
using this type of interface because you don't know the properties that are
needed at compile time. Some select applications will need this. For them,
it would probably be more useful to inflate a property container dynamically
adapting to what is needed. Note that below I have PropertyContainer and not
PropertyCatalog. The intent is that a PropertyContainer would be a new class
for efficiently storing linked lists of data type specific property
containing objects a) polymorphicly interfaced by DA, b) polymorphicly
interfaced in whatever way might be appropriate for the
learn-the-data-at-run-time type of application, and c) with individual
properties efficiently memory managed using primitive type specific free
lists. 

Sorry if I am preempting Ralph here, but here goes an over trivialized
example.

PropertyContainer & potLuck ( catalogX );
PropertyContainerIterator iter = potluck.makeIterator ();

while ( iter != = iter::end () ) {
	iter->displayYourSelf ();
}

PS: Use of an iterator interface might very well be appropriate for private
use by the probe type of application. The iterator interface approach would
be very inappropriate for passing data between dissimilar components
because:

A) Component A, once it has given up an iterator to component B, never knows
when component B is done using its iterator. There can be big problems with
enforcement of mutual exclusion, lifetime management, and above all
interface responsibility clarity (who is responsible for what on either side
of the fence).

B) Its possible for component B to make inconsistent and incomplete property
set changes in component A. 

C) An iterator is easy to implement for linked list property container, but
inefficient (and unnecessarily complex) to implement for an application that
is just interfacing a compile time known structure like MyColor. The
traverse approach works equally well for a linked list of properties and
also for MyColor and therefore from my humble perspective is the more
general approach.

HTH

Jeff








































You seem to be mixing up two things that should be viewed as independent
topics. 

First there is exporting the data. With that we want an interface that is a)
efficient and b) easy for a person that has proprietary data and wants to
interface it via a standard mechanism.

Second there is the application's perspective when he wants to access
unknown proprietary data that has been exported using the standard
interface.


> > Here's my example of what
> > the "pulling"
> >
> >    data_catalog->find("color")->find("red")->toInt()
> >    data_catalog->find("color")->find("green")->toInt()
> >    data_catalog->find("color")->find("blue")->toInt()
> >
> > turns into based on the dataAccess callback mechanism:




> -----Original Message-----
> From: Kay-Uwe Kasemir [mailto:[email protected]]
> Sent: Monday, September 26, 2005 8:58 AM
> To: [email protected]
> Subject: Fwd: data access structures, strings
> 
> 
> 
> Begin forwarded message:
> 
> > From: Kay-Uwe Kasemir <[email protected]>
> > Date: September 26, 2005 10:58:02 EDT
> > To: Jeff Hill <[email protected]>
> > Subject: Re: data access structures, strings
> >
> >
> >
> > On Sep 23, 2005, at 18:43 , Jeff Hill wrote:
> >
> >> its easy enough to write a
> >> convenience library that implements "destination->r =
> >> data_catalog->find("color")->find("red")->toDouble()" on top of
> >> the data
> >> access minimalist interfaces.
> >>
> > Here's my example of what
> > the "pulling"
> >
> >    data_catalog->find("color")->find("red")->toInt()
> >    data_catalog->find("color")->find("green")->toInt()
> >    data_catalog->find("color")->find("blue")->toInt()
> >
> > turns into based on the dataAccess callback mechanism:
> >
> > class PickRGBPieces : public propertyViewer
> > {
> > public:
> >     PickRGBPieces()
> >     { in_color = have_r = have_g = have_b = false; }
> >     bool isValid()
> >     { return !in_color && have_r && have_g && have_b; }
> >     int getR()
> >     { return r; }
> >     int getG()
> >     { return g; }
> >     int getB()
> >     { return b; }
> >     void reveal ( const propertyId &, const double &v, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &id, const int &v, const
> > propertyCatalog &x)
> >     {
> >         if (in_color)
> >         {
> >             if (id == red_id)
> >             {
> >                 r = v;
> >                 have_r = true;
> >             }
> >             else if (id == green_id)
> >             {
> >                 g = v;
> >                 have_g = true;
> >             }
> >             else if (id == blue_id)
> >             {
> >                 b = v;
> >                 have_b = true;
> >             }
> >         }
> >     }
> >     void reveal ( const propertyId &, const unsigned int &v, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &, const long &v, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &, const unsigned long &v, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &, const epicsTime &, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &, const stringSegment &, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &, const enumStateSet & )
> >     {}
> >     void reveal ( const propertyId &, const arraySegment &, const
> > propertyCatalog &x)
> >     {}
> >     void reveal ( const propertyId &id, const propertyCatalog &x)
> >     {
> >         if (id == color_id)
> >         {
> >             in_color = true;
> >             x.traverse(*this);
> >             in_color = false;
> >         }
> >     }
> > private:
> >     bool in_color, have_r, have_g, have_b;
> >     int r, g, b;
> > };
> >
> > PickRGBPieces rgb;
> > data_catalog.traverse(rgb);
> > if (rgb.isValid())
> > {
> >     cout << "Red   : " << rgb.getR() << "\n";
> >     cout << "Green : " << rgb.getG() << "\n";
> >     cout << "Blue  : " << rgb.getB() << "\n";
> > }
> >
> >
> > -Kay
> >



Replies:
Re: data access structures, strings Kay-Uwe Kasemir
RE: data access structures, strings Jeff Hill
References:
Fwd: data access structures, strings Kay-Uwe Kasemir

Navigate by Date:
Prev: Fwd: data access structures, strings Kay-Uwe Kasemir
Next: Re: data access structures, strings Kay-Uwe Kasemir
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Fwd: data access structures, strings Kay-Uwe Kasemir
Next: Re: data access structures, strings Kay-Uwe Kasemir
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·