00001 /* 00002 * map.h 00003 * 00004 * Copyright (C) 2007-2009 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Definition of the basic aesop::map object. 00032 */ 00033 00034 #ifndef AESOP_MAP_MAP_H__ 00035 #define AESOP_MAP_MAP_H__ 00036 00037 // includes -------------------------------------------------------------------- 00038 #include "zone.h" // zone objects 00039 00040 #include <iostream> 00041 00042 00043 namespace aesop { 00044 00045 /// \ingroup aesop_map_mgmt 00046 /// \defgroup aesop_map AESOP Map and Zone Interfaces 00047 /// 00048 /// \n 00049 /// These are the basic Map and Zone definitions. The AESOP framework provides 00050 /// default implementations of these, but developers are free to create their 00051 /// own. 00052 /// 00053 /// See the comments for the Map class. Map and Zone objects are used for 00054 /// static data only. They define the 3D space and its partitioning. They 00055 /// provide the immobile objects in the world. Dynamics within a map are 00056 /// handled by a different software layer (\ref map_dynamics). 00057 /*@{*/ 00058 00059 00060 /// a destination describes a location to which players can be safely moved 00061 struct destination_t { 00062 // constructor, manipulators 00063 destination_t(void) throw() { this->clear(); } 00064 void clear(void) throw() { 00065 id[0] = 0; 00066 rect.clear(); 00067 } 00068 00069 // data fields 00070 char id[eAESOP_IdBufferSize];///< id of start point 00071 rect3d_t rect; ///< 3D rect in zone 00072 }; 00073 00074 00075 00076 /// used by the Map::iterateZones() function 00077 typedef void (*zone_iteration_fn)(IN Zone * zone, 00078 IN void * context); 00079 00080 00081 /// This is the base object used to describe an AESOP map. From a Map 00082 /// interface, it is possible to traverse and find all zones, static 00083 /// content, etc. 00084 /// 00085 /// For the purposes of the AESOP framework, the map defines an arbitrary 3D 00086 /// region of space. That space should be recursively partitioned into Zone 00087 /// objects (see zone.h). 00088 /// 00089 /// Map and Zone objects are intended to be faithful in-memory 00090 /// representations of the static map data as stored on disk. Any dynamic 00091 /// map/zone objects are managed by client objects (such as MapDynamics). 00092 /// 00093 /// Maps need to be threadsafe. In practice this isn't interesting because 00094 /// maps are read-only after they are loaded. Anything that changes (such 00095 /// as objects being added or removed, moving around, etc.) is handled by 00096 /// the MapDynamics library, not the base Map or Zone objects. 00097 /// 00098 /// <b>Maps should never be aware of drawing or rendering!</b> Other 00099 /// code libraries should use map data to handle drawing. See 00100 /// \ref map_drawer for one example. Map and Zone objects are used on the 00101 /// client and server. 00102 class Map { 00103 public: 00104 // virtual destructor -------------------------------------------------- 00105 virtual ~Map(void) throw(); 00106 00107 // aesop::Map class interface methods ----------------------------------- 00108 virtual const char * getId(void) const throw() = 0; 00109 virtual Zone * getRootZone(void) throw() = 0; 00110 virtual Zone * getZone(IN const char * zone_id) = 0; 00111 virtual void iterateZones(IN zone_iteration_fn, 00112 IN void * context) = 0; 00113 virtual const char * getDefaultStartingPointId(void) const throw() = 0; 00114 virtual void getStartingPointIds(OUT VecString& ids) const = 0; 00115 virtual void getStartingPoint(IN const char * id, 00116 OUT destination_t& start) const = 0; 00117 }; 00118 00119 00120 00121 /*@}*/ 00122 //////////////////////////////////////////////////////////////////////////////// 00123 /// 00124 /// \ingroup aesop_map 00125 /// \defgroup loading_maps Loading Maps 00126 /// 00127 /// 00128 /// To load a map, you must first register a MapFormatReader with the 00129 /// MapLoader. Then you can ask the MapLoader to load a map, and it will 00130 /// work with the registered MapFormatReaders to make that happen. 00131 /// 00132 /// See \ref mapzone for a reference implementation. But any MapFormatReader 00133 /// that supports the aesop-map interfaces should work with all other 00134 /// components (server, client, etc.). 00135 /// 00136 /// <b>Why all this indirection?</b> Precisely so that other server code 00137 /// (physics engines, AI, ...) can be kept insulated from map formats. It 00138 /// remains to be seen if that is actually practical! 00139 /// 00140 /// <b>Registration of map format readers is static.</b> That is, once you 00141 /// register a map format reader, the entire process knows about it. For 00142 /// all known use cases, that is acceptable. 00143 /// 00144 /// <b>Order of registration matters!</b> The first reader to claim a map 00145 /// is asked to load it. 00146 /// 00147 //////////////////////////////////////////////////////////////////////////////// 00148 /*@{*/ 00149 00150 00151 /// This is the map loading routine clients should use. It routes 00152 /// to the correct registered \ref MapFormatReader, and notifies the given 00153 /// notification interface of any type IDs encountered. 00154 smart_ptr<Map> loadMap(IN const char * id, 00155 IN const char * path_to_map_file); 00156 00157 00158 00159 /// MapFormatReader: these have to be implemented elsewhere, and then registered 00160 /// with the MapLoader below. 00161 /// 00162 /// <b>The APIs on this interface can be called by multiple threads 00163 /// simultaneously.</b> Anyone who implements this interface must do so in a 00164 /// threadsafe manner! 00165 class MapFormatReader { 00166 public: 00167 // virtual destructor -------------------------------------------------- 00168 virtual ~MapFormatReader(void) throw(); 00169 00170 // aesop::MapFormatReader class interface methods ----------------------- 00171 virtual const char * getDescription(void) = 0; 00172 virtual bool isMyFormat(IN const char * mapId, 00173 IN const char * path_to_map_file) = 0; 00174 virtual smart_ptr<Map> loadMap(IN const char * mapId, 00175 IN const char * path_to_map_file) = 0; 00176 }; 00177 00178 00179 00180 /// This is how you can register a \ref MapFormatReader with the map loader. 00181 void registerMapFormatReader(IN smart_ptr<MapFormatReader>& reader); 00182 00183 00184 00185 }; // aesop namespace 00186 00187 #endif // AESOP_MAP_MAP_H__ 00188