aistate.hpp 2.59 KB
Newer Older
1 2 3 4 5 6
#ifndef AISTATE_H
#define AISTATE_H

#include <typeinfo>
#include <stdexcept>

terrorfisch's avatar
terrorfisch committed
7 8
namespace MWMechanics
{
9

terrorfisch's avatar
terrorfisch committed
10
    /** \brief stores one object of any class derived from Base.
11
     *  Requesting a certain derived class via get() either returns
terrorfisch's avatar
terrorfisch committed
12 13 14 15 16 17 18 19
     * the stored object if it has the correct type or otherwise replaces
     * it with an object of the requested type.
     */
    template< class Base >
    class DerivedClassStorage
    {              
    private:
        Base* mStorage;
20
        
terrorfisch's avatar
terrorfisch committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
        //if needed you have to provide a clone member function
        DerivedClassStorage( const DerivedClassStorage& other );
        DerivedClassStorage& operator=( const DerivedClassStorage& );
        
    public:
        /// \brief returns reference to stored object or deletes it and creates a fitting
        template< class Derived >
        Derived& get()
        {
            Derived* result = dynamic_cast<Derived*>(mStorage);
            
            if(!result)
            {
                if(mStorage)
                    delete mStorage;
                mStorage = result = new Derived();
            }
            
            //return a reference to the (new allocated) object 
            return *result;
        }
42
        
terrorfisch's avatar
terrorfisch committed
43 44
        template< class Derived >
        void store( const Derived& payload )
45 46 47
        {
            if(mStorage)
                delete mStorage;
terrorfisch's avatar
terrorfisch committed
48
            mStorage = new Derived(payload);
49 50
        }
        
terrorfisch's avatar
terrorfisch committed
51 52 53 54 55 56 57 58
        /// \brief takes ownership of the passed object
        template< class Derived >
        void moveIn( Derived* p )
        {
            if(mStorage)
                delete mStorage;
            mStorage = p;
        }
59
        
terrorfisch's avatar
terrorfisch committed
60 61
        bool empty() const
        {
62
            return mStorage == nullptr;
terrorfisch's avatar
terrorfisch committed
63 64 65 66 67 68 69
        }
        
        const std::type_info& getType() const
        {
            return typeid(mStorage);
        }
        
70
        DerivedClassStorage():mStorage(nullptr){}
terrorfisch's avatar
terrorfisch committed
71 72 73 74
        ~DerivedClassStorage()
        {
            if(mStorage)
                delete mStorage;
75
        }
76 77
    };

terrorfisch's avatar
terrorfisch committed
78

terrorfisch's avatar
terrorfisch committed
79 80 81
    /// \brief base class for the temporary storage of AiPackages.
    /**
     * Each AI package with temporary values needs a AiPackageStorage class
82
     * which is derived from AiTemporaryBase. The Actor holds a container
terrorfisch's avatar
terrorfisch committed
83 84 85
     * AiState where one of these storages can be stored at a time.
     * The execute(...) member function takes this container as an argument.
     * */
86 87
    struct AiTemporaryBase
    {
88
        virtual ~AiTemporaryBase(){}
89 90
    };
    
terrorfisch's avatar
terrorfisch committed
91
    /// \brief Container for AI package status.
92 93 94 95
    typedef DerivedClassStorage<AiTemporaryBase> AiState;
}

#endif // AISTATE_H