map.h

Go to the documentation of this file.
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