@@ -38,6 +38,7 @@ source distribution.
3838
3939using namespace tmx ;
4040
41+ // public
4142Tileset::Tileset (const std::string& workingDir)
4243 : m_workingDir (workingDir),
4344 m_firstGID (0 ),
@@ -52,58 +53,66 @@ Tileset::Tileset(const std::string& workingDir)
5253
5354}
5455
55- // public
56- void Tileset::parse (pugi::xml_node node, Map* map)
56+ bool Tileset::loadWithoutMap (const std::string& path)
5757{
58- assert (map);
58+ std::string resolved_path = tmx::resolveFilePath (path, m_workingDir);
59+ std::string contents;
60+ if (!readFileIntoString (resolved_path, &contents))
61+ {
62+ Logger::log (" Failed to read file " + resolved_path, Logger::Type::Error);
63+ return reset ();
64+ }
5965
60- std::string attribString = node.name ();
61- if (attribString != " tileset" )
66+ m_workingDir = getFilePath (resolved_path);
67+ return loadWithoutMapFromString (contents);
68+ }
69+
70+ bool Tileset::loadWithoutMapFromString (const std::string& xmlStr)
71+ {
72+ pugi::xml_document doc;
73+ auto result = doc.load_string (xmlStr.c_str ());
74+ if (!result)
6275 {
63- Logger::log (attribString + " : not a tileset node! Node will be skipped." , Logger::Type::Warning);
64- return ;
76+ Logger::log (" Failed to parse tileset XML" , Logger::Type::Error);
77+ Logger::log (" Reason: " + std::string (result.description ()), Logger::Type::Error);
78+ return false ;
6579 }
66-
67- m_firstGID = node. attribute ( " firstgid " ). as_int ( );
68- if (m_firstGID == 0 )
80+
81+ auto tilesetNode = doc. child ( " tileset " );
82+ if (!tilesetNode )
6983 {
70- Logger::log (" Invalid first GID in tileset. Tileset node skipped. " , Logger::Type::Warning );
71- return ;
84+ Logger::log (" Failed opening tileset: no tileset node found " , Logger::Type::Error );
85+ return reset () ;
7286 }
7387
74- pugi::xml_document tsxDoc; // need to keep this in scope
75- if (node.attribute (" source" ))
88+ return parse (tilesetNode, nullptr );
89+ }
90+
91+ bool Tileset::parse (pugi::xml_node node, Map* map)
92+ {
93+ std::string attribString = node.name ();
94+
95+ // when parsing as part of a map, we may be looking at an inline node that
96+ // refers to another file
97+ if (map)
7698 {
77- // parse TSX doc
78- std::string path = node.attribute (" source" ).as_string ();
79- path = resolveFilePath (path, m_workingDir);
80-
81- // as the TSX file now dictates the image path, the working
82- // directory is now that of the tsx file
83- auto position = path.find_last_of (' /' );
84- if (position != std::string::npos)
85- {
86- m_workingDir = path.substr (0 , position);
87- }
88- else
99+ if (attribString != " tileset" )
89100 {
90- m_workingDir = " " ;
101+ Logger::log (attribString + " : not a tileset node! Node will be skipped." , Logger::Type::Warning);
102+ return false ;
91103 }
92104
93- // see if doc can be opened
94- auto result = tsxDoc.load_file (path.c_str ());
95- if (!result)
105+ m_firstGID = node.attribute (" firstgid" ).as_int ();
106+ if (m_firstGID == 0 )
96107 {
97- Logger::log (path + " : Failed opening tsx file for tile set, tile set will be skipped" , Logger::Type::Error );
98- return reset () ;
108+ Logger::log (" Invalid first GID in tileset. Tileset node skipped. " , Logger::Type::Warning );
109+ return false ;
99110 }
100111
101- // if it can then replace the current node with tsx node
102- node = tsxDoc.child (" tileset" );
103- if (!node)
112+ if (node.attribute (" source" ))
104113 {
105- Logger::log ( " tsx file does not contain a tile set node, tile set will be skipped " , Logger::Type::Error );
106- return reset ( );
114+ std::string path = node. attribute ( " source " ). as_string ( );
115+ return loadWithoutMap (path );
107116 }
108117 }
109118
@@ -227,6 +236,8 @@ void Tileset::parse(pugi::xml_node node, Map* map)
227236 createMissingTile (ID );
228237 }
229238 }
239+
240+ return true ;
230241}
231242
232243std::uint32_t Tileset::getLastGID () const
@@ -249,7 +260,7 @@ const Tileset::Tile* Tileset::getTile(std::uint32_t id) const
249260}
250261
251262// private
252- void Tileset::reset ()
263+ bool Tileset::reset ()
253264{
254265 m_firstGID = 0 ;
255266 m_source = " " ;
@@ -269,6 +280,7 @@ void Tileset::reset()
269280 m_terrainTypes.clear ();
270281 m_tileIndex.clear ();
271282 m_tiles.clear ();
283+ return false ;
272284}
273285
274286void Tileset::parseOffsetNode (const pugi::xml_node& node)
@@ -331,8 +343,6 @@ Tileset::Tile& Tileset::newTile(std::uint32_t ID)
331343
332344void Tileset::parseTileNode (const pugi::xml_node& node, Map* map)
333345{
334- assert (map);
335-
336346 Tile& tile = newTile (node.attribute (" id" ).as_int ());
337347 if (node.attribute (" terrain" ))
338348 {
0 commit comments