• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Cpper
            C/C++高級工程師 Android高級軟件工程師 IT集成工程師 音頻工程師 熟悉c,c++,java,c#,py,js,asp等多種語言 程序猿

            好幾天沒寫博客了
            接著以前寫的Loki系列來

            首先Loki Factory設計的目的就是讓對象功能按名生成!

            該文主要涉及Loki/Factory.h文件
            首先上工廠異常類
            如下:

            /**
             * \defgroup    FactoryErrorPoliciesGroup Factory Error Policies
             * \ingroup        FactoryGroup
             * \brief        Manages the "Unknown Type" error in an object factory
             * 
             * \class DefaultFactoryError
             * \ingroup        FactoryErrorPoliciesGroup
             * \brief        Default policy that throws an exception        
             * 
             
            */

                template 
            <typename IdentifierType, class AbstractProduct>
                
            struct DefaultFactoryError
                {
                    
            struct Exception : public std::exception
                    {
                        
            const char* what() const throw() { return "Unknown Type"; }
                    };

                    
            static AbstractProduct* OnUnknownType(IdentifierType)
                    {
                        
            throw Exception();
                    }
                };
            這里使用了一個模板來處理當出現不可定名的對象標示時的處理方法
            其中Identifier是對象的標示(比如id,字符串等等)
            AbstrctProduct就是工廠產品的基類

            不過感覺如果出現非存在的對象標示時應該返回空的對象指針為不是出現異常
            所以我加入了下面模板
                ////////////////////////////////////////////////////////
                
            /// 定義蓋莫引擎工廠產品制作出錯處理(出錯則返回NULL!)
                
            ////////////////////////////////////////////////////////////
                template <typename IdentifierType, class AbstractProduct>
                
            struct EngineFactoryError
                {
                    
            struct Exception : public std::exception
                    {
                        
            const char* what() const throw() 
                        { 
                            
            return "Not Found"
                        }
                    };

                    
            static AbstractProduct* OnUnknownType(IdentifierType)
                    {
                        
            return NULL; 
                    }
                }; 
            當然這里沒有誰對誰錯的問題



                struct FactoryImplBase
                {
                    typedef EmptyType Parm1;
                    typedef EmptyType Parm2;
                    typedef EmptyType Parm3;
                    typedef EmptyType Parm4;
                    typedef EmptyType Parm5;
                    typedef EmptyType Parm6;
                    typedef EmptyType Parm7;
                    typedef EmptyType Parm8;
                    typedef EmptyType Parm9;
                    typedef EmptyType Parm10;
                    typedef EmptyType Parm11;
                    typedef EmptyType Parm12;
                    typedef EmptyType Parm13;
                    typedef EmptyType Parm14;
                    typedef EmptyType Parm15;
                };

            是一個作為工廠基類的數據結構
            最大可以持有15個模板參數(太多了吧)


               template <typename AP, typename Id, typename TList >
                
            struct FactoryImpl;
            這個前向聲明表明了
            FactoryImpl具有3個模板參數 一個工廠產品指針 一個對象標識  一個對象所在鏈表


                template<typename AP, typename Id>
                
            struct FactoryImpl<AP, Id, NullType>
                            : 
            public FactoryImplBase
                {
                    
            virtual ~FactoryImpl() {}
                    
            virtual AP* CreateObject(const Id & id ) = 0;
                };
            則是對象鏈表為空的特化形式
            通過調用CreateObject來獲取對象指針

            接下來的
            template <typename AP, typename Id, typename P1 >
                
            struct FactoryImpl<AP,Id, Seq<P1> >
                            : 
            public FactoryImplBase
                {
                    typedef typename TypeTraits
            <P1>::ParameterType Parm1;
                    
            virtual ~FactoryImpl() {}
                    
            virtual AP* CreateObject(const Id& id,Parm1 ) = 0;
                };

            一直到 P15大致都是一樣的
            簡單的說Pi說明了名字鏈表的上限

            接下來就是Loki的Factory
            ////////////////////////////////////////////////////////////////////////////////
            ///  \class Factory
            ///
            ///  \ingroup FactoryGroup
            ///  Implements a generic object factory.
            ///
            ///  Create functions can have up to 15 parameters.
            ///
            ///  \par Singleton lifetime when used with Loki::SingletonHolder
            ///  Because Factory uses internally Functors which inherits from
            ///  SmallObject you must use the singleton lifetime
            ///  \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode
            ///  Alternatively you could suppress for Functor the inheritance
            ///  from SmallObject by defining the macro:
            /// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode
            ////////////////////////////////////////////////////////////////////////////////
            從注釋可以看出 她最多支持15個對象鏈表
            再是模板頭
                template
                
            <
                    
            class AbstractProduct,
                    typename IdentifierType,
                    typename CreatorParmTList 
            = NullType,
                    template
            <typename, class> class FactoryErrorPolicy = EngineFactoryError//DefaultFactoryError
                >
            在這里我做了修改并沒有使用其默認的異常處理
            而是采用當出現非法標識時返回空的對象指針的策略
                class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
                {
                    typedef FactoryImpl
            < AbstractProduct, IdentifierType, CreatorParmTList > Impl;

                    typedef typename Impl::Parm1 Parm1;
                    typedef typename Impl::Parm2 Parm2;
                    typedef typename Impl::Parm3 Parm3;
                    typedef typename Impl::Parm4 Parm4;
                    typedef typename Impl::Parm5 Parm5;
                    typedef typename Impl::Parm6 Parm6;
                    typedef typename Impl::Parm7 Parm7;
                    typedef typename Impl::Parm8 Parm8;
                    typedef typename Impl::Parm9 Parm9;
                    typedef typename Impl::Parm10 Parm10;
                    typedef typename Impl::Parm11 Parm11;
                    typedef typename Impl::Parm12 Parm12;
                    typedef typename Impl::Parm13 Parm13;
                    typedef typename Impl::Parm14 Parm14;
                    typedef typename Impl::Parm15 Parm15;

                    typedef Functor
            <AbstractProduct*, CreatorParmTList> ProductCreator;

                    typedef AssocVector
            <IdentifierType, ProductCreator> IdToProductMap;

                    IdToProductMap associations_;
            在這里庫作者使用了AssocVector容器 具體代碼在對等頭文件里面
            構造和析構沒什么說的了
                    Factory()
                        : associations_()
                    {
                    }

                    
            ~Factory()
                    {
                        associations_.erase(associations_.begin(), associations_.end());
                    }
            析構無非是對對象的清空動作
            下面是對象的注冊和反注冊動作
                    bool Register(const IdentifierType& id, ProductCreator creator)
                    {
                        
            return associations_.insert(
                                     typename IdToProductMap::value_type(id, creator)).second 
            != 0;
                    }

                    template 
            <class PtrObj, typename CreaFn>
                    
            bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn)
                    {
                        ProductCreator creator( p, fn );
                        
            return associations_.insert(
                            typename IdToProductMap::value_type(id, creator)).second 
            != 0;
                    }

                    
            bool Unregister(const IdentifierType& id)
                    {
                        
            return associations_.erase(id) != 0;
                    }
            可以看出 如果需要注冊一個新的對象標識
            只需要把對象標示和其對于的Creator加入鏈表即可
            下面的這個函數就是獲取對象標識鏈表
                    std::vector<IdentifierType> RegisteredIds()
                    {
                        std::vector
            <IdentifierType> ids;
                        
            for(typename IdToProductMap::iterator it = associations_.begin();
                            it 
            != associations_.end(); ++it)
                        {
                            ids.push_back(it
            ->first);
                        }
                        
            return ids;
                    }

            之后的16個函數
            AbstractProduct* CreateObject(const IdentifierType& id)
                    {
                        typename IdToProductMap::iterator i 
            = associations_.find(id);
                        
            if (i != associations_.end())
                            
            return (i->second)( );
                        
            return this->OnUnknownType(id);
                    }
            ...
            是對象的生成動作
            可以看出
            如果在鏈表中沒有發現給定標識則模板異常策略發生作用

            代碼最后是復制工廠
            /**
             *   \defgroup    CloneFactoryGroup Clone Factory
             *   \ingroup    FactoriesGroup
             *   \brief        Creates a copy from a polymorphic object.
             *
             *   \class        CloneFactory
             *   \ingroup    CloneFactoryGroup
             *   \brief        Creates a copy from a polymorphic object.
             
            */

                template
                
            <
                    
            class AbstractProduct,
                    
            class ProductCreator =
                        AbstractProduct
            * (*)(const AbstractProduct*),
                    template
            <typename, class>
                        
            class FactoryErrorPolicy = DefaultFactoryError
                
            >
                
            class CloneFactory
                    : 
            public FactoryErrorPolicy<TypeInfo, AbstractProduct>
                {
                
            public:
                    
            bool Register(const TypeInfo& ti, ProductCreator creator)
                    {
                        
            return associations_.insert(
                            typename IdToProductMap::value_type(ti, creator)).second 
            != 0;
                    }

                    
            bool Unregister(const TypeInfo& id)
                    {
                        
            return associations_.erase(id) != 0;
                    }

                    AbstractProduct
            * CreateObject(const AbstractProduct* model)
                    {
                        
            if (model == NULL)
                        {
                            
            return NULL;
                        }

                        typename IdToProductMap::iterator i 
            = 
                            associations_.find(typeid(
            *model));
                            
                        
            if (i != associations_.end())
                        {
                            
            return (i->second)(model);
                        }
                        
            return this->OnUnknownType(typeid(*model));
                    }

                
            private:
                    typedef AssocVector
            <TypeInfo, ProductCreator> IdToProductMap;
                    IdToProductMap associations_;
                };
                    


            其復制過程為
            首先檢測復制源是否為空為空則返回空指針
            然后根據對象名字獲取她在標識-產品鏈表中的迭代器位置
            如果存在則返回復制
            否則根據處置的異常處理策略處理它!

            Loki Factory看完了 不過感覺有點華而不實
            本來蓋莫游戲引擎期望采用這個現在看來需要另外寫了

            下面是一大堆亂代碼O(∩_∩)O~


            ////////////////////////////////////////////////////////////
            /// 重定義引擎對象鏈表數據類型
            ////////////////////////////////////////////////////////////

            typedef Loki::Seq
            <   
                
            //! 在這里添加新的類型
                #include <GEngine/Template/RegisterObject.inl>
            >::Type ObjectList;

            namespace Loki
            {

                
            ////////////////////////////////////////////////////////
                
            /// 定義蓋莫引擎工廠產品制作出錯處理(出錯則返回NULL!)
                
            ////////////////////////////////////////////////////////////

                /*template <typename IdentifierType, class AbstractProduct>
                struct EngineFactoryError
                {
                    struct Exception : public std::exception
                    {
                        const char* what() const throw() 
                        { 
                            return "Not Found"; 
                        }
                    };

                    static AbstractProduct* OnUnknownType(IdentifierType)
                    {
                        return NULL; 
                    }
                };
            */
             

            }


            namespace core
            {

            ////////////////////////////////////////////////////////////
            /// 重定義蓋莫游戲引擎對象工廠類型
            ////////////////////////////////////////////////////////////

            typedef Loki::SingletonHolder
            <
                Loki::Factory
            <Object,engine_string> 
            >   ObjectFactory;

            static inline bool RegisterObject(engine_string key,RefPtr<Object>(*Creator)())
            {
                
            return ObjectFactory::Instance().Register(key,Creator);
            }


            ////////////////////////////////////////////////////////////
            /// 定義蓋莫游戲引擎工廠基類(Interface必須是RefCount的子類)
            ////////////////////////////////////////////////////////////

            template<typename Interface>
            class Factory 
            {
                
            virtual RefPtr<Interface> Create() = 0;
            }
            ;
             
            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品
            ////////////////////////////////////////////////////////////

            template<class Product,class AbstractProduct>
            RefPtr
            <AbstractProduct> CreateNewObject()
            {
                
            return new Product;                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品(模板特化)
            ////////////////////////////////////////////////////////////

            template<class Product>
            RefPtr
            <Product> CreateNewObject()
            {
                
            return new Product();                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品
            ////////////////////////////////////////////////////////////

            template<class Product,class AbstractProduct,class P1>
            RefPtr
            <AbstractProduct> CreateNewObject(P1 p1)
            {
                
            return new Product(p1);                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品(模板特化)
            ////////////////////////////////////////////////////////////

            template<class Product,class P1>
            RefPtr
            <Product> CreateNewObject(P1 p1)
            {
                
            return new Product(p1);                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品
            ////////////////////////////////////////////////////////////

            template<class Product,class AbstractProduct,class P1,class P2>
            RefPtr
            <AbstractProduct> CreateNewObject(P1 p1,P2 p2)
            {
                
            return new Product(p1,p2);                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品(模板特化)
            ////////////////////////////////////////////////////////////

            template<class Product,class P1,class P2>
            RefPtr
            <Product> CreateNewObject(P1 p1,P2 p2)
            {
                
            return new Product(p1,p2);                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品
            ////////////////////////////////////////////////////////////

            template<class Product,class AbstractProduct,class P1,class P2,class P3>
            RefPtr
            <AbstractProduct> CreateNewObject(P1 p1,P2 p2,P3 p3)
            {
                
            return new Product(p1,p2,p3);                
            }


            ////////////////////////////////////////////////////////////
            /// 獲取一個新的工廠產品(模板特化)
            ////////////////////////////////////////////////////////////

            template<class Product,class P1,class P2,class P3>
            RefPtr
            <Product> CreateNewObject(P1 p1,P2 p2,P3 p3)
            {
                
            return new Product(p1,p2,p3);                
            }


            }

             

            #define REGISTER_FUNCTION(Object)\
            namespace Loki\
            {\
                template
            <> \
                
            bool RegisterFunction<Object>()\
                
            {\
                    
            return RegisterObject(#Object,&core::CreateNewObject<Object>);\
                }
            \
            }
                
                
            /*#define REGISTER_FUNCTION1(Object)\
                template<> \
                bool RegisterFunction<Object>()\
                {\
                    return RegisterObject(#Object,&core::CreateNewObject<Object>);\
                }

            #define REGISTER_FUNCTION2(Object)\
                template<> \
                bool RegisterFunction<Object>()\
                {\
                    return RegisterObject(#Object,&core::CreateNewObject<Object>);\
                }

            #define REGISTER_FUNCTION3(Object)\
                template<> \
                bool RegisterFunction<Object>()\
                {\
                    return RegisterObject(#Object,&core::CreateNewObject<Object>);\
                }

            #define REGISTER_FUNCTION4(Object)\
                template<> \
                bool RegisterFunction<Object>()\
                {\
                    return RegisterObject(#Object,&core::CreateNewObject<Object>);\
                }
            */
                 
              
             
            #define UNREGISTER_FUNCTION(Object)\
            namespace Loki\
            {\
                template
            <> \
                
            bool UnRegisterFunction<Object>()\
                
            {\
                    
            return true;\
                }
            \
            }
                

            #define GlobalGetNewObjectByName(name)\
                core::ObjectFactory::Instance().CreateObject(name);



             

            posted on 2010-05-05 21:29 ccsdu2009 閱讀(2084) 評論(6)  編輯 收藏 引用
            Comments
            • # re: Loki技法6-Factory
              陳梓瀚(vczh)
              Posted @ 2010-05-06 08:52
              #define CLASS_NAMES(F)\
              F(classA)\
              F(classB)\
              F(classC)\
              F(classD)


              就夠了。傳入不同的F可以生成不同的代碼。于是只要你把factory的框架通過CLASS_NAMES建立起來,以后就只需要每次多加一行。  回復  更多評論   
            • # re: Loki技法6-Factory
              99書城
              Posted @ 2010-05-06 11:53
              商店凡客時間地方空間  回復  更多評論   
            • # re: Loki技法6-Factory
              夢在天涯
              Posted @ 2010-05-06 12:56
              loki好東東啊,mark  回復  更多評論   
            • # re: Loki技法6-Factory
              ccsdu2009
              Posted @ 2010-05-06 16:09
              @陳梓瀚(vczh)
              #include <GEngine/Template/RegisterObject.inl>

              感覺這個不是我想要的東西  回復  更多評論   
            • # re: Loki技法6-Factory[未登錄]
              helloworld
              Posted @ 2010-05-07 13:28
              loki沒用,這種到處是模板的代碼,有何用處?什么項目會用?囧  回復  更多評論   
            • # re: Loki技法6-Factory
              ccsdu2009
              Posted @ 2010-05-07 16:58
              @helloworld
              stl到處也是模板!  回復  更多評論   
             
            久久99精品久久久久久hb无码| 精品国产乱码久久久久久1区2区| 久久久久无码精品国产| 久久这里只精品99re66| 久久综合久久综合九色| 精品久久久久中文字幕日本| 欧美激情一区二区久久久| 亚洲精品国产综合久久一线| 久久国产热精品波多野结衣AV| 亚洲国产精品一区二区久久hs | 久久无码国产| 精品久久久久中文字幕一区| 国产成人精品久久亚洲| 久久综合久久综合九色| 久久综合欧美成人| 国产精品免费久久| 老司机午夜网站国内精品久久久久久久久 | 亚洲人AV永久一区二区三区久久 | 婷婷久久综合九色综合98| www.久久热.com| 欧美亚洲另类久久综合| 久久97久久97精品免视看秋霞| 久久99精品久久久久久秒播| 久久久久久国产精品免费免费| 久久亚洲av无码精品浪潮| 久久久久这里只有精品| 模特私拍国产精品久久| 伊人久久大香线蕉综合影院首页 | …久久精品99久久香蕉国产| 国产精品久久久久影视不卡| 品成人欧美大片久久国产欧美| 久久激情五月丁香伊人| 亚洲国产天堂久久综合| 亚洲AV日韩精品久久久久久| 久久成人国产精品二三区| 久久精品国产第一区二区| 麻豆av久久av盛宴av| 91精品国产高清91久久久久久| 狠狠久久综合| 性欧美丰满熟妇XXXX性久久久 | 久久99精品久久久久久|