ObjectResource.h

Go to the documentation of this file.
00001 /*
00002  * The information in this file is
00003  * Copyright(c) 2007 Ball Aerospace & Technologies Corporation
00004  * and is subject to the terms and conditions of the
00005  * GNU Lesser General Public License Version 2.1
00006  * The license text is available from   
00007  * http://www.gnu.org/licenses/lgpl.html
00008  */
00009 
00010 #ifndef OBJECTRESOURCE_H
00011 #define OBJECTRESOURCE_H
00012 
00013 #include <string>
00014 
00015 #include "ApplicationServices.h"
00016 #include "ModelServices.h"
00017 #include "ObjectFactory.h"
00018 #include "Resource.h"
00019 #include "TypeConverter.h"
00020 
00021 /**
00022  * This is a base class for Traits to the %Resource template. 
00023  *
00024  * This is a base class for Traits to the %Resource template. It provides a quick
00025  * method for getting the ObjectFactory pointer that the derived classes need.
00026  * It also contains the Args class.
00027  * 
00028  * @see FactoryResource
00029  */
00030 class FactoryAllocator
00031 {
00032 public:
00033    /**
00034    * This is an implementation detail of the %FactoryAllocator class. 
00035    *
00036    * This is an implementation detail of the %FactoryAllocator class. It is used 
00037    * for passing the parameters required by ObjectFactory::createObject.
00038    */
00039    class Args
00040    {
00041    public:
00042       std::string mType;
00043       Args(std::string type) : mType(type) {}
00044       Args(const char* type) : mType(type) {}
00045    };
00046 protected:
00047    ObjectFactory* getFactory() const
00048    {
00049       Service<ApplicationServices> pApplication;
00050       return pApplication->getObjectFactory();
00051    }
00052 };
00053 /**
00054  * The %FactoryObject is a trait object for use with the %Resource template. 
00055  *
00056  * The %FactoryObject is a trait object for use with the %Resource template. It provides capability for
00057  * getting and returning objects from the ObjectFactory.
00058  * 
00059  * @see FactoryResource
00060  */
00061 class FactoryObject : public FactoryAllocator
00062 {
00063 public:
00064    void* obtainResource(const Args& args) const
00065    { 
00066       return getFactory()->createObject(args.mType.c_str()); 
00067    }
00068    void releaseResource(const Args& args, void* pObject) const
00069    { 
00070       getFactory()->destroyObject(pObject, args.mType.c_str());
00071    }
00072 };
00073 /**
00074  * The %FactoryVector is a trait object for use with the %Resource template. 
00075  *
00076  * The %FactoryVector is a trait object for use with the %Resource template. It provides capability for
00077  * getting and returning vectors of objects from the ObjectFactory.
00078  * 
00079  * @see FactoryResource
00080  */
00081 class FactoryVector : public FactoryAllocator
00082 {
00083 public:
00084    void* obtainResource(const Args& args) const
00085    { 
00086       return getFactory()->createObjectVector(args.mType.c_str()); 
00087    }
00088    void releaseResource(const Args& args, void* pVector) const
00089    { 
00090       getFactory()->destroyObjectVector(pVector, args.mType.c_str());
00091    }
00092 };
00093 
00094 typedef FactoryAllocator::Args FactoryArgs;
00095 
00096 /**
00097  *  This is a %Resource class that wraps an object from the ObjectFactory. 
00098  *
00099  *  This is a %Resource class that wraps an object from the ObjectFactory. 
00100  *  When the %FactoryResource object goes out of scope, the object
00101  *  will be returned to the ObjectFactory.
00102  *
00103  *  @code
00104  *  void addPixels(AoiElement *pAoi)
00105  *  {
00106  *     FactoryResource<BitMask> pMask; // gets BitMask from the ObjectFactory
00107  *     for (int i=0; i<100; ++i)
00108  *        for (int j=0; j<100; ++j)
00109  *           if ((i^j) & 0x1) pMask->setPixel (i, j);
00110  *     pAoi->addPoints (pMask.get ());
00111  *  } // BitMask returned to ObjectFactory here
00112  *  @endcode
00113  *
00114  *  @see ObjectFactory
00115  */
00116 template<class T>
00117 class FactoryResource : public Resource<T, FactoryObject>
00118 {
00119 public:
00120    explicit FactoryResource() :
00121       Resource<T, FactoryObject>(TypeConverter::toString<T>())
00122    {
00123    }
00124 
00125    explicit FactoryResource<T>(T* pObject) :
00126       Resource<T, FactoryObject>(pObject, typename Resource<T, FactoryObject>::Args(TypeConverter::toString<T>()))
00127    {
00128    }
00129 };
00130 
00131 /**
00132  * The %ModelObject is a trait object for use with the %Resource template. 
00133  *
00134  * The %ModelObject is a trait object for use with the %Resource template. It provides capability for
00135  * getting and returning objects from ModelServices.
00136  * 
00137  * @see ModelResource
00138  */
00139 class ModelObject
00140 {
00141 public:
00142    /**
00143     * This is an implementation detail of the %ModelObject class.
00144     *
00145     * This is an implementation detail of the %ModelObject class. It is used 
00146     * for passing the parameters required by ModelServices::create.
00147     */
00148    class Args
00149    {
00150    public:
00151       Args() :
00152          mpDescriptor(NULL),
00153          mpParent(NULL)
00154       {
00155       }
00156 
00157       Args(std::string name, std::string type, DataElement* pParent = NULL) :
00158          mpDescriptor(NULL),
00159          mName(name),
00160          mType(type),
00161          mpParent(pParent)
00162       {
00163       }
00164 
00165       Args(DataDescriptor* pDescriptor) :
00166          mpDescriptor(pDescriptor),
00167          mpParent(NULL)
00168       {
00169       }
00170 
00171       DataDescriptor* mpDescriptor;
00172       std::string mName;
00173       std::string mType;
00174       DataElement* mpParent;
00175    };
00176 
00177    void* obtainResource(const Args& args) const
00178    {
00179       Service<ModelServices> pModel;
00180       DataDescriptor* pDescriptor = args.mpDescriptor;
00181       if (pDescriptor == NULL)
00182       {
00183          pDescriptor = pModel->createDataDescriptor(args.mName.c_str(), args.mType.c_str(),
00184             args.mpParent);
00185       }
00186       if (pDescriptor != NULL)
00187       {
00188          DataElement* pElement = pModel->createElement(pDescriptor);
00189          pModel->destroyDataDescriptor(pDescriptor);
00190          return pElement;
00191       }
00192 
00193       return NULL;
00194    }
00195    void releaseResource(const Args& args, DataElement* pObject) const
00196    {
00197       Service<ModelServices>()->destroyElement(pObject);
00198    }
00199 };
00200 typedef ModelObject::Args ModelArgs;
00201 
00202 /**
00203  *  This is a %Resource class that wraps an object from ModelServices. 
00204  *
00205  *  This is a %Resource class that wraps an object from ModelServices. 
00206  *  When the %ModelResource object goes out of scope, the object
00207  *  will be returned to ModelServices.
00208  *
00209  *  @code
00210  *  void addPixels(AoiElement *pAoi)
00211  *  {
00212  *     ModelResource<AoiElement> pAoi2("MyAoi");
00213  *     for (int i=0; i<100; ++i)
00214  *        for (int j=0; j<100; ++j)
00215  *           if ((i^j) & 0x1) pAoi2->addPoint (i, j);
00216  *     pAoi->merge (pAoi2.get ());
00217  *  } // AOI returned to ModelServices here
00218  *  @endcode
00219  *
00220  *  @see ModelServices
00221  */
00222 template<class T>
00223 class ModelResource : public Resource<T, ModelObject>
00224 {
00225 public:
00226    explicit ModelResource(std::string name, DataElement* pParent = NULL, std::string type = std::string()) :
00227       Resource<T, ModelObject>(
00228          typename Resource<T, ModelObject>::Args(name, type.empty() ? TypeConverter::toString<T>() : type, pParent))
00229    {
00230    }
00231 
00232    /**
00233     * Create a ModelResource for the given descriptor.
00234     *
00235     * @param pDescriptor
00236     *        The DataDescriptor which describes the desired DataElement.
00237     *        ModelResource takes ownership of this object.  It is not
00238     *        safe to dereference pDescriptor after creating the ModelResource.
00239     */
00240    explicit ModelResource(DataDescriptor *pDescriptor) :
00241       Resource<T, ModelObject>(typename Resource<T, ModelObject>::Args(pDescriptor))
00242    {
00243    }
00244 
00245    /**
00246     * Create a ModelResource which owns the provided element and will
00247     * destroy it when the resource is destroyed.
00248     *
00249     * @param pElement the element that will be owned by this resource.
00250     */
00251    explicit ModelResource(T* pElement) :
00252       Resource<T, ModelObject>(pElement, typename Resource<T, ModelObject>::Args())
00253    {
00254    }
00255 };
00256 
00257 class DataDescriptor;
00258 
00259 class DataDescriptorObject
00260 {
00261 public:
00262    typedef ModelObject::Args Args;
00263 
00264    void* obtainResource(const Args& args) const
00265    {
00266       if (args.mpDescriptor == NULL)
00267       {
00268          return Service<ModelServices>()->createDataDescriptor(args.mName.c_str(), args.mType.c_str(),
00269                                                                      args.mpParent);
00270       }
00271 
00272       return args.mpDescriptor;
00273    }
00274    void releaseResource(const Args& args, DataDescriptor* pObject) const
00275    {
00276       Service<ModelServices>()->destroyDataDescriptor(pObject);
00277    }
00278 };
00279 
00280 template<class T>
00281 class DataDescriptorResource : public Resource<T, DataDescriptorObject>
00282 {
00283 public:
00284    explicit DataDescriptorResource(std::string name, std::string dataDescriptorType, DataElement* pParent = NULL) :
00285       Resource<T, DataDescriptorObject>(
00286          typename Resource<T, DataDescriptorObject>::Args(name, dataDescriptorType, pParent))
00287    {
00288    }
00289 
00290    explicit DataDescriptorResource(T* pDescriptor) :
00291       Resource<T, DataDescriptorObject>(typename Resource<T, DataDescriptorObject>::Args(pDescriptor))
00292    {
00293    }
00294 };
00295 
00296 class ImportDescriptorObject
00297 {
00298 public:
00299    class Args
00300    {
00301    public:
00302       Args() :
00303          mpDescriptor(NULL),
00304          mpDataDescriptor(NULL),
00305          mpParent(NULL),
00306          mImported(false)
00307       {
00308       }
00309 
00310       Args(std::string name, std::string type, DataElement* pParent, bool imported) :
00311          mpDescriptor(NULL),
00312          mpDataDescriptor(NULL),
00313          mName(name),
00314          mType(type),
00315          mpParent(pParent),
00316          mImported(imported)
00317       {
00318       }
00319 
00320       Args(std::string name, std::string type, const std::vector<std::string>& parent, bool imported) :
00321          mpDescriptor(NULL),
00322          mpDataDescriptor(NULL),
00323          mName(name),
00324          mType(type),
00325          mpParent(NULL),
00326          mParent(parent),
00327          mImported(imported)
00328       {
00329       }
00330 
00331       Args(ImportDescriptor* pDescriptor) :
00332          mpDescriptor(pDescriptor),
00333          mpDataDescriptor(NULL),
00334          mpParent(NULL),
00335          mImported(false)
00336       {
00337       }
00338 
00339       Args(DataDescriptor* pDescriptor, bool imported) :
00340          mpDescriptor(NULL),
00341          mpDataDescriptor(pDescriptor),
00342          mpParent(NULL),
00343          mImported(imported)
00344       {
00345       }
00346 
00347       ImportDescriptor* mpDescriptor;
00348       DataDescriptor* mpDataDescriptor;
00349       std::string mName;
00350       std::string mType;
00351       DataElement* mpParent;
00352       std::vector<std::string> mParent;
00353       bool mImported;
00354    };
00355 
00356    void* obtainResource(const Args& args) const
00357    {
00358       if (args.mpDescriptor == NULL && args.mpDataDescriptor == NULL)
00359       {
00360          if (args.mpParent == NULL && !args.mParent.empty())
00361          {
00362             return Service<ModelServices>()->createImportDescriptor(args.mName, args.mType,
00363                                                                      args.mParent, args.mImported);
00364          }
00365          return Service<ModelServices>()->createImportDescriptor(args.mName, args.mType,
00366                                                                      args.mpParent, args.mImported);
00367       }
00368       else if (args.mpDescriptor == NULL)
00369       {
00370          return Service<ModelServices>()->createImportDescriptor(args.mpDataDescriptor, args.mImported);
00371       }
00372 
00373       return args.mpDescriptor;
00374    }
00375    void releaseResource(const Args &args, ImportDescriptor *pObject) const
00376    {
00377       Service<ModelServices>()->destroyImportDescriptor(pObject);
00378    }
00379 };
00380 
00381 class ImportDescriptorResource : public Resource<ImportDescriptor, ImportDescriptorObject>
00382 {
00383 public:
00384    explicit ImportDescriptorResource(std::string name, std::string dataDescriptorType, DataElement* pParent = NULL,
00385                                      bool imported = true) :
00386       Resource<ImportDescriptor, ImportDescriptorObject>(Args(name, dataDescriptorType, pParent, imported))
00387    {
00388    }
00389 
00390    explicit ImportDescriptorResource(std::string name, std::string dataDescriptorType,
00391                                      const std::vector<std::string>& parent, bool imported = true) :
00392       Resource<ImportDescriptor, ImportDescriptorObject>(Args(name, dataDescriptorType, parent, imported))
00393    {
00394    }
00395 
00396    explicit ImportDescriptorResource(ImportDescriptor* pDescriptor) :
00397       Resource<ImportDescriptor, ImportDescriptorObject>(Args(pDescriptor))
00398    {
00399    }
00400 
00401    explicit ImportDescriptorResource(DataDescriptor* pDescriptor, bool imported = true) :
00402       Resource<ImportDescriptor, ImportDescriptorObject>(Args(pDescriptor, imported))
00403    {
00404    }
00405 };
00406 
00407 /**
00408  * This is an implementation detail of the ObjectArray class. 
00409  *
00410  * This is an implementation detail of the ObjectArray class. It is used 
00411  * for passing the size parameter required by new[].
00412  */
00413 class ObjectArrayArgs
00414 {
00415 public:
00416    ObjectArrayArgs(int size, bool noThrow) :
00417       mSize(size),
00418       mNoThrow(noThrow)
00419    {
00420    }
00421 
00422    int mSize;
00423    bool mNoThrow;
00424 };
00425 
00426 /**
00427  * The %ObjectArray is a trait object for use with the %Resource template. 
00428  *
00429  * The %ObjectArray is a trait object for use with the %Resource template.
00430  * It provides capability for creating and deleting arrays of objects from the local heap.
00431  * 
00432  * @see ArrayResource
00433  */
00434 template<class T>
00435 class ObjectArray
00436 {
00437 public:
00438    typedef ObjectArrayArgs Args;
00439    T* obtainResource(const Args& args) const 
00440    {
00441       if (args.mSize != 0)
00442       {
00443          if (args.mNoThrow)
00444          {
00445             return new (std::nothrow) T[args.mSize];
00446          }
00447 
00448          return new T[args.mSize];
00449       }
00450 
00451       return NULL;
00452    }
00453 
00454    void releaseResource(const Args& args, T* pObject) const
00455    {
00456       delete [] pObject;
00457    }
00458 };
00459 
00460 typedef ObjectArrayArgs ArrayArgs;
00461 
00462 /**
00463  *  This is a %Resource class that wraps an array of objects on the local heap.
00464  *
00465  *  This is a %Resource class that wraps an array of objects on the local heap.
00466  *  It is in effect a %Resource<T,MemoryObject> except that the ObjectArray
00467  *  SourceTrait uses the [] versions of new and delete. It also supports a
00468  *  range checking indexing method called 'at' that functions similarly to
00469  *  the method of the same name on std::vector and std::deque. Since it
00470  *  uses new[], it will use the default constructor to make the objects of
00471  *  type T. The primary reasons for using an %ArrayResource in place of a
00472  *  std::vector is for the different ownership semantics, and that a copy
00473  *  is not made when ownership is transfered. An %ArrayResource can be
00474  *  returned from a method without making a copy of the contained data.
00475  *
00476  *  @code
00477  *  {
00478  *     ArrayResource<double> pArray(12); // allocate an array of 12 doubles
00479  *     for (int i=0; i<12; ++i)
00480  *        pArray = cos(3.141592654/12.0 * i);
00481  *  } // delete [] called on pArray here
00482  *  @endcode
00483  *
00484  *  @see ObjectFactory
00485  */
00486 template<class T>
00487 class ArrayResource : public Resource<T, ObjectArray<T> >
00488 {
00489 public:
00490    /**
00491     *  Constructs the %Resource object based on a newly allocated heap array.
00492     *
00493     *  Essentially, this allocates and wraps an array
00494     *  in the Resource and assigns the Resource object the responsibility for freeing the array.
00495     *
00496     *  @param   args
00497     *           The arguments that would have been provided to the obtainResource method of the ObjectArray class.
00498     */
00499    explicit ArrayResource(const typename Resource<T, ObjectArray<T> >::Args& args) :
00500       Resource<T, ObjectArray<T> >(args)
00501    {
00502    }
00503 
00504    /**
00505     *  Constructs the %Resource object based on a newly allocated heap array.
00506     *
00507     *  Essentially, this allocates and wraps an array
00508     *  in the Resource and assigns the Resource object the responsibility for freeing the array.
00509     *
00510     *  @param   size
00511     *           The number of objects in the array.
00512     *  @param   noThrow
00513     *           The behavior for a failed allocation.
00514     *           \c True to return \c NULL from get(), \c false to throw \c std::bad_alloc from this constructor.
00515     */
00516    explicit ArrayResource(int size, bool noThrow = false) :
00517       Resource<T, ObjectArray<T> >(typename Resource<T, ObjectArray<T> >::Args(size, noThrow))
00518    {
00519    }
00520 
00521    /**
00522     *  Constructs the %Resource object based on an existing heap array.
00523     *
00524     *  Essentially, this wraps the array
00525     *  in the Resource and assigns the Resource object the responsibility for freeing the array.
00526     *
00527     *  @param   pObject
00528     *           The array to wrap in the Resource.
00529     *  @param   args
00530     *           The arguments that would have been provided to the obtainResource method of the ObjectArray class.
00531     */
00532    ArrayResource(T* pObject, const typename Resource<T, ObjectArray<T> >::Args& args) :
00533       Resource<T, ObjectArray<T> >(pObject, args)
00534    {
00535    }
00536 
00537    /**
00538     *  Constructs the %Resource object based on an existing heap array.
00539     *
00540     *  Essentially, this wraps the array
00541     *  in the Resource and assigns the Resource object the responsibility for freeing the array.
00542     *
00543     *  @param   pObject
00544     *           The array to wrap in the Resource.
00545     *  @param   size
00546     *           The number of objects in the array.
00547     *  @param   noThrow
00548     *           The behavior for a failed allocation.
00549     *           \c True to return \c NULL from get(), \c false to throw \c std::bad_alloc from this constructor.
00550     */
00551    ArrayResource(T* pObject, int size, bool noThrow = false) :
00552       Resource<T, ObjectArray<T> >(pObject, typename Resource<T, ObjectArray<T> >::Args(size, noThrow))
00553    {
00554    }
00555 
00556    ArrayResource(const Resource<T, ObjectArray<T> >& source) :
00557       Resource<T, ObjectArray<T> >(source)
00558    {
00559    }
00560 
00561    /**
00562     *  Returns the number of objects contained in the underlying array.
00563     *
00564     *  @return   The number of objects contained in the underlying array.
00565     */
00566    int size() const
00567    {
00568       return Resource<T, ObjectArray<T> >::getArgs().mSize;
00569    }
00570 
00571    /**
00572     *  Returns a reference to the indexed object.
00573     *
00574     *  Indexes into the underlying array and returns a
00575     *  reference to the indexed object. If the index is out
00576     *  of bounds, based on the Args object, it will throw
00577     *  an exception.
00578     *
00579     *  @param   index
00580     *           The index of the object in the underlying array.
00581     *
00582     *  @return   A reference to the underlying indexed object.
00583     */
00584    T& at(int index) const
00585    {
00586       if (index >= size())
00587       {
00588          throw std::exception("Range Error in ArrayResource");
00589       }
00590 
00591       return Resource<T, ObjectArray<T> >::operator[](index);
00592    }
00593 };
00594 
00595 #endif

Software Development Kit - Opticks 4.9.0 Build 16218