Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Genericmanager - Ethernet

Iniciado por ethernet, 26 de Febrero de 2004, 09:16:37 PM

« anterior - próximo »

ethernet

 
    GenericManager  



    En estos dias de examenes que, curiosamente, te apetece programar mas de lo normal he programado en  ratos libres este GenericManager. Lo cierto es que no añade nada nuevo y hace no mucho mas que la clase que publico Gunder en edevi ( http://209.50.244.56/edevi/nums/3/article....e.php?f=coc.php ) pero tiene cosas que pueden ser interesantes.

    En mi caso uso este manager en dos casos que pueden servir como ejemplos:


    typedef patterns::GenericManager<Texture,TextureLoader<GLTexture> > TextureManager;
    typedef patterns::GenericManager<Texture,TextureLoader<GLTexture> >::Item TextureItem;


    De esta forma se puede usar asi:


    TextureItem textureid = TextureManager::Instance()->GetItem("Textura.tga");

    (quizas ponga mi genericfactory algun dia y pegue el ejemplo de TextureLoader :)

    Otra forma de uso es la siguiente:


    class ShaderManager
    :public patterns::GenericManager<Shader,Shader,std::string,false,ShaderManager>
    {
    ...
    };


    de forma que al coger la instacia con el Metodo Instace retornara una instacia a ShaderManager (parece que no pero tiene su intringulis)


    Sin mas el codigo es el siguiente:

    namespace patterns
    {


    struct
    manager_null_type {};

    //con precache siepre hay una instacia de cada item, solo se borran al final
    template <class Type,class Super = Type,class Key = std::string, bool Create_if_not_exists = true,class Manager = manager_null_type >
    class
    GenericManager
    {


        typedef
     GenericManager<Type,Super,Key,Create_if_not_exists,Manager> ManagerType;
        //hack para evitar recursividad en el template
            template <class T>
            struct
    manager_traits
            {

                typedef
    T manager ;
            };

            template
    <>
            struct
    manager_traits<manager_null_type>
            {

                  typedef
    GenericManager<Type,Super,Key,Create_if_not_exists,manager_null_type> manager;
            };

         //fin hack
        public:
            typedef
    Type ItemBase;
           class
    Item
           {

                friend
    ManagerType;
              Type *p;
              GenericManager *parent;
              const
    Key *__key;
              int
    *__count;
          
              Item(const Key &s,GenericManager *p,Type *_p,int *c):
                   __key(&s),
                   parent(p),
                   __count(c),
                   p(_p)
                   {}

            public
    :
                 /*explicit*/
    Item(const Item &i = NullItem()):
                __key(i.__key),
                 parent(i.parent),
                __count(i.__count),
                
                p(i.p)
                {

                   add_ptr();
                }

             Item& operator=(const Item& other)
             {

                   if
    (&other == this) return *this;
                release_ptr();
                __count = other.__count;
                p = other.p;
                parent = other.parent;
                   __key = other.__key;
                add_ptr();
                return
    *this;
             }

             
             void
    release_ptr()
             {

                if
    (__count &&!--(*__count)) parent->ReleaseItem(this);
             }

               void
    add_ptr()
               {

                   if
    (__count) ++(*__count);
               }

               void
    __debug_info()
               {

                   debuglog <<  "key: " << *__key << endl;
                   debuglog <<  "count: " << *__count << endl;

               }


           public
    :
              ~
    Item()
              {

                 release_ptr();

              }

              operator
    bool()
              {

                 return
    p!=0;
              }

              Type *operator->()
              {

                 return
    p;
              }

              static
    Item NullItem()
              {

                   static
    Item nullitem("",0,0,0);
                return
    nullitem;
              }

                friend
    bool operator==(const Item &i,const Item &o)
                {

                    if
    (i.p == o.p) return true;
                    else return
    false;
                }

                friend
    bool operator!=(const Item &i,const Item &o)
                {

                    if
    (i.p != o.p) return true;
                    else return
    false;
                }
           };

          

       private
    :
           struct
    TypeCount
           {

              TypeCount(Type *_p):
                p(_p),count(1){}
              Type *p;
              int
    count;
           };

           typedef
    std::map<Key,TypeCount*> TypeMap;
           TypeMap Map;
          
        protected
    :
           GenericManager()
           {}

          
        public
    :
          
           ~
    GenericManager()
           {

              TypeMap::iterator i = Map.begin();
              for
    (;i!= Map.end();++i)
                {

                    debuglog << "deleting..." << (*i).first << endl;
                    delete
    (*i).second->p;
                    delete
    (*i).second;
                }
             
             
           }

            //friend class manager_traits;
           static manager_traits<Manager>::manager* Instance()
           {

               static
    manager_traits<Manager>::manager gm;
             return
    &gm;
           }

       
           Item GetItem(const Key &key)
           {

                       debuglog << "GetItem:: searching " << key.c_str() << endl;                  
                   TypeMap::iterator it = Map.find(key);
                   if
    (it == Map.end())
                   {

                           debuglog << "*NOT FOUND!*" << endl;
                      if
    (Create_if_not_exists)
                      {

                               if
    (!CreateItem(key)) return Item::NullItem() ;
                           }

                           else return
    Item::NullItem() ;
                           it = Map.find(key);
                   }
       
                       debuglog << "*FOUND!*" << endl;
                   TypeCount *i = (*it).second;//Map[key];                           
                       return Item((*it).first,this,i->p,&i->count);
           }

           bool
    CreateItem(const Key &key,Super *sp = 0)
           {

                      debuglog << "CreateItem::creating... " << key.c_str() << endl;
                   TypeMap::iterator it = Map.find(key);
                   if
    (it == Map.end())
                   {
                   
                      Type *p;
                      if
    (sp)  p = sp;
                      else

                          {
       
                              p = new Super(key);                    
                          if
    (!p)  return false;                 
                          }

                      Map[key] = new TypeCount(p);
                      //p->__key = const_cast(&(*Map.find(key)).first);
                      return true;
                   }

                   return
    false;              
                 
           }

           void
    ReleaseItem(Item *item)
           {

                //pre-erase [virtual]
              TypeMap::iterator i = Map.find(*item->__key);
              delete
    item->p;
              delete
    (*i).second;
              Map.erase(i);
           }

            void
    __debug_info()
            {

                   debuglog << "numitems: " << Map.size() << endl;
                   TypeMap::iterator i = Map.begin();
                   for
    (;i!=Map.end();++i)
                   {

                       debuglog << (*i).first << " :" << (*i).second->count << endl;
                   }
                 

            }
    };

    };


    [/list]



CoLSoN2

 parece interesante. Buen trabajo (ole)

template madness rlz
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.