interreality.org [VOS]
[Home] [About]
[Screenshots]
[Download]
[News]
[Community]
[Documentation] [Manual]
[Bugs & Requests] [Wiki]

/home/tetron/hack/vos/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    - Creating metaobjects
00006    - How to use the property metaobject
00007 
00008    This file (vostut5server.cc) is released into the public domain.  No
00009    restrictions are placed on its use, distribution or inclusion into
00010    other works.
00011 */
00012 
00013 // You must run this program before running vostut5client.
00014 
00015 #include <vos/vos/vos.hh>
00016 
00017 using namespace VUtil;
00018 using namespace VOS;
00019 
00020 #ifdef WIN32
00021 #define sleep _sleep
00022 #endif
00023 
00024 void listTypes(Vobject* vob);
00025 
00026 int main(int argc, char** argv)
00027 {
00028     std::cout << "VOS Tutorial 5 Server\n\n";
00029 
00030     Site localsite;
00031     localsite.addSiteExtension(new LocalVipSiteExtension());
00032     localsite.setDefaultPolicy("core:accept-all");
00033 
00034     /* When you create a data structure out of several Vobjects as we
00035        did in the previous tutorial, the various objects will take on
00036        different tasks.  The "sphere" object acts as a container for
00037        the other objects, the "position" stores the position value,
00038        the "radius" stores the radius and so forth.  It is not
00039        sufficient to differentiate vobjects by their parent-child
00040        relationships, however.  It may obvious be that the object
00041        named "sphere" describes a sphere, but what if we want to name
00042        it "ball" or "planet"?
00043 
00044        A Vobject may have a set of "types" associated with it.  A
00045        type is simply an agreed-upon string which indicates to the
00046        application that this Vobject adheres to a certain interface.
00047        This interface may be that the Vobject has certain children
00048        with specific meanings (a child named "position" describes its
00049        position, for example) or it may indicate that the Vobject
00050        accepts or generates certain types of messages.  A Vobject can
00051        have several type strings, indicating that it adheres to
00052        multiple standands simultaneously (it is up to the user to
00053        avoid conflicts).
00054 
00055        When creating an object, list the types it supports. You can
00056        list up to five type strings.
00057      */
00058     vRef<Vobject> planet = localsite.createVobjectA("planet", "tutorial:sphere");
00059     planet->setDefaultPolicy("core:accept-all");
00060 
00061     listTypes(planet);
00062 
00063 
00064     // We can also add types:
00065     planet->addType("tutorial:class-M");
00066     listTypes(planet);
00067 
00068 
00069     /* Use getTypes() to get the type set.  The hasItem() method scans
00070        the type set for the desired item.
00071     */
00072     if(planet->getTypes().hasItem("tutorial:class-M")) {
00073         std::cout << "vostut5server: It it a habitable planet.\n";
00074     }
00075 
00076     /* If it occured to you that the type of a Vobject could be
00077        similar to class of a C++ object, you're right on track.  VOS
00078        allows you set up a mapping between Vobject types and C++
00079        classes.  This allows you to implement a C++ interface for the
00080        operations on that Vobject corresponding to a particular object
00081        type.  This is acomplished by using the MetaObject class to
00082        dynamically extend the capabilities of a given Vobject.  This
00083        tutorial demonstrates how to create a vobject with the
00084        "Property" extension.
00085 
00086        The easiest way to add an extension is to specify it when you
00087        create a Vobject.  This is done using a template, and the
00088        return type will be the first templated type:
00089     */
00090     vRef<Property> positionproperty = localsite.createVobject<Property>("position");
00091 
00092     /* The "positionproperty" object allows us to access methods
00093        specific to the property extension.  We can access the usual
00094        Vobject API (insertChild, getTypes, etc) through
00095        "positionproperty" well.
00096     */
00097     listTypes(positionproperty);
00098 
00099     planet->insertChild(-1, "position", positionproperty);
00100 
00101     /* Perhaps you are wondering what the Property extension actually
00102        does!  This extension defines a standard way for storing and
00103        accessing a block of data in a Vobject.  It is very much like a
00104        file, with read() and write() methods.  The property metaobject
00105        is used by nearly everything as the common way of storing
00106        simple data in a Vobject.
00107     */
00108 
00109     /* To set a property's value, use replace().  The first parameter
00110        is the new contents of the property, the second parameter is
00111        the datatype of the property's value (such as a MIME type).
00112     */
00113     positionproperty->replace("1 2 3", "list: float");
00114 
00115 
00116     // To read a property value, use read()
00117 
00118     std::cout << "vostut5server: The property value of " << positionproperty->getURL().getString()
00119               << " is " << positionproperty->read() << std::endl;
00120 
00121 
00122     /* You can selectively change a part of a property using write().
00123        The first argument is the offset, the second is the new section.
00124     */
00125     positionproperty->write(2, "4");
00126 
00127     std::cout << "vostut5server: The property value of " << positionproperty->getURLstr()
00128               << " is now " << positionproperty->read() << std::endl;
00129 
00130 
00131     /* We must set an access control policy for remote users.  This
00132        policy is used to control what actions are permitted on this
00133        object.  Here we are using a read-only policy, so remote users
00134        will be able to read but not change the value of this property.
00135     */
00136     positionproperty->setDefaultPolicy("property:read-only");
00137 
00138     std::cout << "Going into runloop now.\n";
00139     while(true) sleep(1000);
00140 }
00141 
00142 void listTypes(Vobject* vob)
00143 {
00144     std::cout << "Types for " << vob->getURL().getString() << ": ";
00145     for(TypeSetIterator types = vob->getTypes(); types.hasMore(); types++)
00146     {
00147         if(!types.atStart()) std::cout << ", ";
00148         std::cout << (*types);
00149     }
00150     std::cout << "\n";
00151 }
00152