instance.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                              *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 #ifndef FIFE_INSTANCE_H
00023 #define FIFE_INSTANCE_H
00024 
00025 // Standard C++ library includes
00026 #include <vector>
00027 
00028 // 3rd party library includes
00029 
00030 // FIFE includes
00031 // These includes are split up in two parts, separated by one empty line
00032 // First block: files included from the FIFE root src directory
00033 // Second block: files included from the same folder
00034 #include "util/base/fifeclass.h"
00035 
00036 #include "model/metamodel/object.h"
00037 #include "model/metamodel/ivisual.h"
00038 
00039 #include "location.h"
00040 
00041 
00042 namespace FIFE {
00043 
00044     class Layer;
00045     class Action;
00046     class Instance;
00047     class ActionInfo;
00048     class SayInfo;
00049     class TimeProvider;
00050 
00051     class InstanceActionListener {
00052     public:
00053         virtual ~InstanceActionListener() {};
00054         virtual void onInstanceActionFinished(Instance* instance, Action* action) = 0;
00055         virtual void onInstanceActionFrame(Instance* instance, Action* action, int32_t frame) = 0;
00056     };
00057 
00058     enum InstanceChangeType {
00059         ICHANGE_NO_CHANGES = 0x0000,
00060         ICHANGE_LOC = 0x0001,
00061         ICHANGE_FACING_LOC = 0x0002,
00062         ICHANGE_SPEED = 0x0004,
00063         ICHANGE_ACTION = 0x0008,
00064         ICHANGE_TIME_MULTIPLIER = 0x0010,
00065         ICHANGE_SAYTEXT = 0x0020,
00066         ICHANGE_ROTATION = 0x0040,
00067         ICHANGE_BLOCK = 0x0080,
00068         ICHANGE_CELL = 0x0100
00069     };
00070     typedef uint32_t InstanceChangeInfo;
00071 
00072     class InstanceChangeListener {
00073     public:
00074         virtual ~InstanceChangeListener() {};
00075         virtual void onInstanceChanged(Instance* instance, InstanceChangeInfo info) = 0;
00076     };
00077 
00078 
00079     class InstanceDeleteListener {
00080     public:
00081         virtual ~InstanceDeleteListener() {};
00082         virtual void onInstanceDeleted(Instance* instance) =0;
00083     };
00084 
00088     class Instance : public FifeClass, public InstanceDeleteListener {
00089     public:
00090 
00095         Instance(Object* object, const Location& location, const std::string& identifier="");
00096 
00099         virtual ~Instance();
00100 
00103         const std::string& getId() { return m_id; }
00104 
00107         void setId(const std::string& identifier="");
00108 
00111         Object* getObject() { return m_object; }
00112 
00116         void setLocation(const Location& loc);
00117 
00122         Location getLocation() const { return m_location; }
00123 
00127         Location& getLocationRef() { return m_location; }
00128 
00135         Location getTargetLocation() const;
00136 
00140         void setFacingLocation(const Location& loc);
00141 
00146         Location getFacingLocation();
00147 
00150         void setRotation(int32_t rotation);
00151 
00154         int32_t getRotation() const { return m_rotation; }
00155 
00162         Location& getFacingLocationRef();
00163 
00166         void setBlocking(bool blocking);
00167 
00170         bool isBlocking() const;
00171 
00174         void setOverrideBlocking(bool overblock) { m_override_blocking = overblock; }
00175 
00178         bool isOverrideBlocking() const { return m_override_blocking; }
00179 
00184         void callOnActionFrame(Action* action, int32_t frame);
00185 
00189         void addActionListener(InstanceActionListener* listener);
00190 
00194         void removeActionListener(InstanceActionListener* listener);
00195 
00199         void addChangeListener(InstanceChangeListener* listener);
00200 
00204         void removeChangeListener(InstanceChangeListener* listener);
00205 
00209         void addDeleteListener(InstanceDeleteListener* listener);
00210 
00214         void removeDeleteListener(InstanceDeleteListener* listener);
00215 
00220         Action* getCurrentAction() const;
00221 
00226         double getMovementSpeed() const;
00227 
00232         uint32_t getActionRuntime();
00233 
00239         void setActionRuntime(uint32_t time_offset);
00240 
00247         void move(const std::string& action_name, const Location& target, const double speed);
00248 
00254         void act(const std::string& action_name, const Location& direction, bool repeating=false);
00255 
00260         void say(const std::string& text, uint32_t duration=0);
00261 
00268         void follow(const std::string& action_name, Instance* leader, const double speed);
00269 
00272         const std::string* getSayText() const;
00273 
00279         InstanceChangeInfo update();
00280 
00283         bool isActive() const;
00284 
00287         void setVisual(IVisual* visual) { m_visual = visual; }
00288 
00291         template<typename T> T* getVisual() const { return reinterpret_cast<T*>(m_visual); }
00292 
00295         void setTimeMultiplier(float multip);
00296 
00299         float getTimeMultiplier();
00300 
00303         float getTotalTimeMultiplier();
00304 
00308         uint32_t getRuntime();
00309 
00313         void refresh();
00314 
00317         inline InstanceChangeInfo getChangeInfo();
00318 
00321         void onInstanceDeleted(Instance* instance);
00322 
00323     private:
00324         std::string m_id;
00325 
00326         // The rotation offset of this instance. This is in addition to possible camera rotation and
00327         // intended for setting, for example, a rotation of a tile.
00328         int32_t m_rotation;
00329 
00338         class InstanceActivity {
00339         public:
00340             InstanceActivity(Instance& source);
00341             ~InstanceActivity();
00342 
00343             // ----- Fields related to change tracking -----
00344             // updates cached variables, marks changes
00345             void update(Instance& source);
00346             // location on previous round
00347             Location m_location;
00348             // rotation on previous round
00349             int32_t m_rotation;
00350             // facing location on previous round
00351             Location m_facinglocation;
00352             // action on previous round. @NOTE: might become invalid, only used for address comparison
00353             Action* m_action;
00354             // speed on previous round
00355             double m_speed;
00356             // time multiplier on previous round
00357             float m_timemultiplier;
00358             // say text on previous round
00359             std::string m_saytxt;
00360             // listeners for changes
00361             std::vector<InstanceChangeListener*> m_changelisteners;
00362 
00363             // ----- Fields related to generic activity -----
00364             // listeners for action related events
00365             std::vector<InstanceActionListener*> m_actionlisteners;
00366             // action information, allocated when actions are bind
00367             ActionInfo* m_actioninfo;
00368             // text to say + duration, allocated when something is said
00369             SayInfo* m_sayinfo;
00370             // time scaler for this instance
00371             TimeProvider* m_timeprovider;
00372             // blocking status on previous round
00373             bool m_blocking;
00374         };
00375         InstanceActivity* m_activity;
00376         // bitmask stating current changes
00377         InstanceChangeInfo m_changeinfo;
00378         // listeners for deletion of the instance
00379         std::vector<InstanceDeleteListener*> m_deletelisteners;
00380 
00381         // object where instantiated from
00382         Object* m_object;
00383         // current location
00384         Location m_location;
00385         // current facing location. Just a pointer to save space e.g. on tiles
00386         Location* m_facinglocation;
00387         // instance visualization
00388         IVisual* m_visual;
00389         // instance blocking info
00390         bool m_blocking;
00391         // allow to override the blocking property
00392         bool m_override_blocking;
00393 
00394         Instance(const Instance&);
00395         Instance& operator=(const Instance&);
00396         // Finalize current action
00397         void finalizeAction();
00398         // Initialize action for use
00399         void initializeAction(const std::string& action_name);
00400         // Moves instance. Returns true if finished
00401         bool process_movement();
00402         // Calculates movement based current location and speed
00403         void calcMovement();
00404         // rebinds time provider based on new location
00405         void bindTimeProvider();
00406         // called when instance has been changed. Causes instance to create InstanceActivity
00407         void initializeChanges();
00408     };
00409 
00410     inline InstanceChangeInfo Instance::getChangeInfo() {
00411         if (m_activity) {
00412             return m_changeinfo;
00413         }
00414         return ICHANGE_NO_CHANGES;
00415     }
00416 } // FIFE
00417 
00418 #endif