Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

apps/tutorials/vostut5server.cc

Go to the documentation of this file.
00001 /* Fifth VOS tutorial.  Introduction to Metaobjects.
00002 
00003    This tutorial file covers:
00004    - Vobject types
00005    - Registering metaobject extenders
00006    - Creating metaobjects
00007    - The meta_cast<> template
00008    - How to use the property metaobject
00009 
00010    This file (vostut5server.cc) is released into the public domain.  No
00011    restrictions are placed on its use, distribution or inclusion into
00012    other works.
00013 */
00014 
00015 // You must run this program before running vostut5client.
00016 
00017 #include <vos/corelibs/vos/vos.hh>
00018 #include <vos/metaobjects/property/property.hh>
00019 
00020 void listTypes(Vobject* vob);
00021 
00022 int main(int argc, char** argv)
00023 {
00024     cout << "VOS Tutorial 5 Server\n\n";
00025 
00026     LocalSocketSite localsite(&NoAccessControl::static_);
00027     localsite.setTimeoutOnSelect(-1);
00028 
00029     /* When you create a data structure out of several Vobjects as we
00030        did in the previous tutorial, the various objects will take on
00031        different tasks.  The "sphere" object acts as a container for
00032        the other objects, the "position" stores the position value,
00033        the "radius" stores the radius and so forth.  It is not
00034        sufficient to differentiate vobjects by their parent-child
00035        relationships, however.  It may obvious be that the object
00036        named "sphere" describes a sphere, but what if we want to name
00037        it "ball" or "planet"?
00038 
00039        A Vobject may have a list of "types" associated with it.  A
00040        type is simply an agreed-upon string which indicates to the
00041        application that this Vobject adheres to a certain interface.
00042        This interface may be that the Vobject has certain children
00043        with specific meanings (a child named "position" describes its
00044        position, for example) or it may indicate that the Vobject
00045        accepts and generates certain types of messages.  A Vobject can
00046        have several type strings, indicating that it adheres to
00047        multiple standands simultaneously (it is up to the user to
00048        avoid conflicts).
00049 
00050        When creating an object, we list the types it supports.  This
00051        is variable-argument method (eg it uses "...") so you must
00052        always have a 0 to indicate the end of the list.
00053      */
00054     vRef<Vobject> planet = localsite.createMetaObject("planet", "tutorial:sphere", 0);
00055 
00056     listTypes(&planet);
00057 
00058 
00059     // We can add types:
00060     planet->addType("tutorial:class M");
00061     listTypes(&planet);
00062 
00063 
00064     // You can check to see if a type is present on a Vobject using
00065     // the count() method.  Technically this returns the number of
00066     // time the type shows up in the set, but because it is a set of
00067     // unique elements this will always be either 1 or 0.
00068 
00069     if(planet->getTypes().count("tutorial:class M")) {
00070         cout << "vostut5server: It it a habitable planet.\n";
00071     }
00072 
00073     /* If it occured to you that the type of a Vobject could be
00074        similar to class of a C++ object, you're right on track.  VOS
00075        allows you to automatically map a Vobject type to a C++ class.
00076        The class then implements a C++ method interface for the
00077        operations on that Vobject.  Using the MetaObject class called
00078        you can dynamically extend the capabilities of a given Vobject.
00079        This tutorial demonstrates how to create a vobject which
00080        implements functionality from the "Property" extension.
00081     */
00082 
00083     // First we must register the Property extension with VOS.  This
00084     // should only ever be done once, in the initialization of your
00085     // program.
00086     Property::registerExtenders();
00087 
00088 
00089     /* typeid() is a part of the C++ language which provides some
00090        information about C++ classes.  The name() method gives us a
00091        unique name which refers specifically to that class.  By
00092        calling Property::registerExtenders(), we have associated the
00093        C++ Property class with a certain Vobject type and type
00094        extension.  The createMetaObject method adds that extension to
00095        the newly created MetaObject.
00096 
00097        Here's another way of looking at it: we would like the new
00098        Vobject we are creating to have the C++ interface defined by
00099        the "Property" class, we ask createMetaObject to extend the
00100        Vobject appropriately to support this.
00101     */
00102     vRef<MetaObject> position = localsite.createMetaObject("position", typeid(Property).name(), 0);
00103 
00104     listTypes(&position);
00105 
00106     planet->insertChild(-1, "position", &position);
00107 
00108 
00109     /* To extract the Property class interface from the position
00110        vobject, we use the template method MetaObject::meta_cast<>.
00111        Given a Vobject or MetaObject, meta_cast<> returns the desired
00112        c++ interface to that vobject if available, or NULL if not.
00113        Think of it as an elaborate typecast.
00114     */
00115     Property* positionproperty = MetaObject::meta_cast<Property*>(&position);
00116 
00117     /* The "positionproperty" object allows us to access methods
00118        specific to the property extension.  We can access the usual
00119        Vobject API (insertChild, getTypes, etc) through
00120        "positionproperty" well. */
00121 
00122     /* Perhaps you have been wondering what the Property extension
00123        actually does!  This extension defines a standard way for
00124        storing and accessing a block of data in a Vobject.  It is very
00125        much like a file, with read() and write() methods.  The
00126        property metaobject is used by nearly everything else as a
00127        common way of storing data in a Vobject.
00128     */
00129 
00130     // To set a property's value, use replace().  The first parameter
00131     // is the new contents of the property, the second parameter is
00132     // the datatype of the property's value (such as a MIME type).
00133 
00134     positionproperty->replace("1 2 3", "text/x-vector-float");
00135 
00136 
00137     // To read a property value, use read()
00138 
00139     cout << "vostut5server: The property value of " << positionproperty->getURL().getString()
00140          << " is " << positionproperty->read() << endl;
00141 
00142 
00143     // You can selectively change a part of a property using write().
00144     // The first argument is the offset, the second is the new section.
00145 
00146     positionproperty->write(2, "4");
00147 
00148     cout << "vostut5server: The property value of " << positionproperty->getURL().getString()
00149          << " is now " << positionproperty->read() << endl;
00150 
00151 
00152     /* "LocalProperty" is a subclass of "Property" which implements
00153        the property type as a local vobject, answering queries from
00154        remote vobjects.  Because "Property" is an abstract class which
00155        can represent both local and remote properties, we must
00156        meta_cast to LocalProperty to set the access control.
00157     */
00158     LocalProperty* localproperty = MetaObject::meta_cast<LocalProperty*>(&position);
00159 
00160     /* We must set an access control policy for remote users.  This
00161        policy is used to control what actions are permitted on this
00162        object.  There can actually be a "chain" of access control
00163        policies; the first parameter indicates that the new policy
00164        should be added to the end of the chain.  We are using a
00165        read-only policy, so remote users will be able to read but not
00166        change the value of this property.
00167     */
00168     localproperty->insertPropertyAccessControl(-1, &ReadOnlyPropertyAccessControl::static_);
00169 
00170 
00171     cout << "Going into runloop now.\n";
00172 
00173     while(true) {
00174         localsite.flushIncomingBuffers();
00175     }
00176 }
00177 
00178 void listTypes(Vobject* vob)
00179 {
00180     // The type set is returned as an STL set<string>.  Simply use
00181     // standard iterators to iterate over the set.
00182 
00183     const Vobject::TypeSet& types = vob->getTypes();
00184 
00185     cout << "Types for " << vob->getURL().getString() << ": ";
00186     for(Vobject::TypeSet::const_iterator i = types.begin(); i != types.end(); i++)
00187     {
00188         if(i != types.begin()) cout << ", ";
00189         cout << (*i);
00190     }
00191     cout << "\n";
00192 }
00193 

Generated on Tue Aug 12 03:55:36 2003 for Interreality Project - VOS by doxygen 1.3.2