renderernode.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
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 // Standard C++ library includes
00023 
00024 // 3rd party library includes
00025 
00026 // FIFE includes
00027 // These includes are split up in two parts, separated by one empty line
00028 // First block: files included from the FIFE root src directory
00029 // Second block: files included from the same folder
00030 #include "video/renderbackend.h"
00031 #include "util/math/fife_math.h"
00032 #include "util/log/logger.h"
00033 #include "model/structures/instance.h"
00034 #include "model/structures/layer.h"
00035 #include "model/structures/location.h"
00036 #include "view/camera.h"
00037 
00038 #include "renderernode.h"
00039 
00040 
00041 namespace FIFE {
00042     static Logger _log(LM_VIEWVIEW);
00043 
00044     class NodeInstanceDeleteListener : public InstanceDeleteListener {
00045     public:
00046         NodeInstanceDeleteListener(RendererNode* node)  {
00047             m_node = node;
00048         }
00049         virtual ~NodeInstanceDeleteListener() {}
00050 
00051         virtual void onInstanceDeleted(Instance* instance) {
00052             m_node->removeInstance(instance, false);
00053         }
00054 
00055     private:
00056         RendererNode* m_node;
00057     };
00058 
00059     RendererNode::RendererNode(Instance* attached_instance, const Location &relative_location, Layer* relative_layer, const Point &relative_point):
00060         m_instance(NULL),
00061         m_location(relative_location),
00062         m_layer(relative_layer),
00063         m_point(relative_point),
00064         m_listener(NULL) {
00065         addInstance(attached_instance);
00066     }
00067     RendererNode::RendererNode(Instance* attached_instance, const Location &relative_location, const Point &relative_point):
00068         m_instance(NULL),
00069         m_location(relative_location),
00070         m_layer(NULL),
00071         m_point(relative_point),
00072         m_listener(NULL) {
00073         addInstance(attached_instance);
00074     }
00075     RendererNode::RendererNode(Instance* attached_instance, Layer* relative_layer, const Point &relative_point):
00076         m_instance(NULL),
00077         m_location(NULL),
00078         m_layer(relative_layer),
00079         m_point(relative_point),
00080         m_listener(NULL) {
00081         addInstance(attached_instance);
00082     }
00083     RendererNode::RendererNode(Instance* attached_instance, const Point &relative_point):
00084         m_instance(NULL),
00085         m_location(NULL),
00086         m_layer(NULL),
00087         m_point(relative_point),
00088         m_listener(NULL) {
00089         addInstance(attached_instance);
00090     }
00091     RendererNode::RendererNode(const Location &attached_location, Layer* relative_layer, const Point &relative_point):
00092         m_instance(NULL),
00093         m_location(attached_location),
00094         m_layer(relative_layer),
00095         m_point(relative_point),
00096         m_listener(NULL) {
00097     }
00098     RendererNode::RendererNode(const Location &attached_location, const Point &relative_point):
00099         m_instance(NULL),
00100         m_location(attached_location),
00101         m_layer(NULL),
00102         m_point(relative_point),
00103         m_listener(NULL) {
00104     }
00105     RendererNode::RendererNode(Layer* attached_layer, const Point &relative_point):
00106         m_instance(NULL),
00107         m_location(NULL),
00108         m_layer(attached_layer),
00109         m_point(relative_point),
00110         m_listener(NULL) {
00111     }
00112     RendererNode::RendererNode(const Point &attached_point):
00113         m_instance(NULL),
00114         m_location(NULL),
00115         m_layer(NULL),
00116         m_point(attached_point),
00117         m_listener(NULL) {
00118     }
00119     RendererNode::RendererNode(const RendererNode& old):
00120         m_instance(NULL),
00121         m_location(old.m_location),
00122         m_layer(old.m_layer),
00123         m_point(old.m_point),
00124         m_listener(NULL) {
00125         addInstance(old.m_instance);
00126     }
00127     RendererNode& RendererNode::operator=(const RendererNode &source) {
00128         if (this != &source) {
00129             changeInstance(source.m_instance);
00130             m_location = source.m_location;
00131             m_layer = source.m_layer;
00132             m_point = source.m_point;
00133         }
00134         return *this;
00135     }
00136     RendererNode::~RendererNode() {
00137         removeInstance(m_instance);
00138         delete m_listener;
00139     }
00140 
00141     void RendererNode::setAttached(Instance* attached_instance, const Location &relative_location, const Point &relative_point) {
00142         changeInstance(attached_instance);
00143         m_location = relative_location;
00144         m_point = relative_point;
00145     }
00146     void RendererNode::setAttached(Instance* attached_instance, const Location &relative_location) {
00147         changeInstance(attached_instance);
00148         m_location = relative_location;
00149     }
00150     void RendererNode::setAttached(Instance* attached_instance, const Point &relative_point) {
00151         changeInstance(attached_instance);
00152         m_point = relative_point;
00153     }
00154     void RendererNode::setAttached(Instance* attached_instance) {
00155         changeInstance(attached_instance);
00156     }
00157     void RendererNode::setAttached(const Location &attached_location, const Point &relative_point) {
00158         changeInstance(NULL);
00159         m_location = attached_location;
00160         m_point = relative_point;
00161     }
00162     void RendererNode::setAttached(const Location &attached_location) {
00163         changeInstance(NULL);
00164         m_location = attached_location;
00165     }
00166     void RendererNode::setAttached(Layer* attached_layer) {
00167         m_layer = attached_layer;
00168     }
00169     void RendererNode::setAttached(const Point &attached_point) {
00170         changeInstance(NULL);
00171         m_location = NULL;
00172         m_point = attached_point;
00173     }
00174 
00175     void RendererNode::setRelative(const Location &relative_location) {
00176         if(m_instance == NULL) {
00177             FL_WARN(_log, LMsg("RendererNode::setRelative(Location) - ") << "No instance attached.");
00178         }
00179         m_location = relative_location;
00180     }
00181     void RendererNode::setRelative(const Location &relative_location, Point relative_point) {
00182         if(m_instance == NULL) {
00183             FL_WARN(_log, LMsg("RendererNode::setRelative(Location, Point) - ") << "No instance attached.");
00184         }
00185         m_location = relative_location;
00186         m_point = relative_point;
00187     }
00188     void RendererNode::setRelative(const Point &relative_point) {
00189         if(m_instance == NULL || m_location == NULL) {
00190             FL_WARN(_log, LMsg("RendererNode::setRelative(Point) - ") << "No instance or location attached.");
00191         }
00192         m_point = relative_point;
00193     }
00194 
00195     Instance* RendererNode::getAttachedInstance() {
00196         if(m_instance == NULL) {
00197             FL_WARN(_log, LMsg("RendererNode::getAttachedInstance() - ") << "No instance attached.");
00198         }
00199         return m_instance;
00200     }
00201     Location RendererNode::getAttachedLocation() {
00202         if(m_instance != NULL || m_location == NULL) {
00203             FL_WARN(_log, LMsg("RendererNode::getAttachedLocation() - ") << "No location attached.");
00204         }
00205         return m_location;
00206     }
00207     Layer* RendererNode::getAttachedLayer() {
00208         if(m_layer == NULL) {
00209             FL_WARN(_log, LMsg("RendererNode::getAttachedLayer() - ") << "No layer attached.");
00210         }
00211         return m_layer;
00212     }
00213     Point RendererNode::getAttachedPoint() {
00214         if(m_instance != NULL || m_location != NULL) {
00215             FL_WARN(_log, LMsg("RendererNode::getAttachedPoint() - ") << "No point attached.");
00216         }
00217         return m_point;
00218     }
00219 
00220     Location RendererNode::getOffsetLocation() {
00221         if(m_instance == NULL || m_location == NULL) {
00222             FL_WARN(_log, LMsg("RendererNode::getOffsetLocation() - ") << "No location as offset used.");
00223         }
00224         return m_location;
00225     }
00226     Point RendererNode::getOffsetPoint() {
00227         if(m_instance == NULL && m_location == NULL) {
00228             FL_WARN(_log, LMsg("RendererNode::getOffsetPoint() - ") << "No point as offset used.");
00229         }
00230         return m_point;
00231     }
00232 
00233     Instance* RendererNode::getInstance() {
00234         return m_instance;
00235     }
00236     Location RendererNode::getLocation() {
00237         return m_location;
00238     }
00239     const Location& RendererNode::getLocationRef() {
00240         return m_location;
00241     }
00242     Layer* RendererNode::getLayer() {
00243         return m_layer;
00244     }
00245     Point RendererNode::getPoint() {
00246         return m_point;
00247     }
00248     const Point& RendererNode::getPointRef() {
00249         return m_point;
00250     }
00251 
00252     void RendererNode::addInstance(Instance* instance) {
00253         checkDeleteListener();
00254         m_instance = instance;
00255         if (m_instance) {
00256             m_instance->addDeleteListener(m_listener);
00257         }
00258     }
00259 
00260     void RendererNode::changeInstance(Instance* instance) {
00261         if (m_instance == instance) {
00262             return;
00263         }
00264         checkDeleteListener();
00265         if (m_instance) {
00266             m_instance->removeDeleteListener(m_listener);
00267         }
00268         m_instance = instance;
00269         if (m_instance) {
00270             m_instance->addDeleteListener(m_listener);
00271         }
00272     }
00273 
00274     void RendererNode::removeInstance(Instance* instance, bool listener) {
00275         if (m_instance == instance && instance) {
00276             if (listener) {
00277                 m_instance->removeDeleteListener(m_listener);
00278             }
00279             m_instance = NULL;
00280         }
00281     }
00282 
00283     void RendererNode::checkDeleteListener() {
00284         if (m_listener) {
00285             return;
00286         }
00287         m_listener = new NodeInstanceDeleteListener(this);
00288     }
00289 
00290     Point RendererNode::getCalculatedPoint(Camera* cam, Layer* layer, const bool zoomed) {
00291         ScreenPoint p;
00292         if(m_instance != NULL) {
00293             if(m_layer == NULL) {
00294                 m_layer = m_instance->getLocationRef().getLayer();
00295             }
00296             if(m_location != NULL) {
00297                 p = cam->toScreenCoordinates(m_instance->getLocationRef().getMapCoordinates() + m_location.getMapCoordinates());
00298             } else {
00299                 p = cam->toScreenCoordinates(m_instance->getLocationRef().getMapCoordinates());
00300             }
00301         } else if(m_location != NULL) {
00302             if(m_layer == NULL) {
00303                 m_layer = m_location.getLayer();
00304             }
00305             p = cam->toScreenCoordinates(m_location.getMapCoordinates());
00306         } else if(m_layer == NULL) {
00307             // FIXME
00308             FL_WARN(_log, LMsg("RendererNode::getCalculatedPoint(Camera, Layer) - ") << "No layer attached. So we use the first active layer of the renderer.");
00309             setAttached(layer);
00310         }
00311         if(zoomed) {
00312             return Point(round(m_point.x * cam->getZoom()) + p.x, round(m_point.y * cam->getZoom()) + p.y);
00313         } else {
00314             return Point(m_point.x + p.x, m_point.y + p.y);
00315         }
00316 
00317     }
00318 }