File: Game.cpp

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (114 lines) | stat: -rw-r--r-- 2,612 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "Game.h"

#include "itextstream.h"
#include "iregistry.h"
#include "xmlutil/Document.h"
#include <iostream>

namespace game
{

const std::string Game::FILE_EXTENSION(".game");

Game::Game(const std::string& path, const std::string& filename)
{
	std::string fullPath = path + filename;

	// Load the XML file by constructing an xml::Document object
	// and search for the <game> tag
	xml::Document doc(fullPath);

	if (!doc.isValid())
	{
		rError() << "Could not parse XML file: " << fullPath << std::endl;
		return;
	}

	// Check for a toplevel game node
	xml::NodeList list = doc.findXPath("/game");

	if (list.empty())
	{
	    rError() << "Couldn't find <game> node in the game description file " << fullPath << std::endl;
		return;
	}

	const xml::Node& node = list.front();

	// Get the game name
	_name = node.getAttributeValue("name");

	const std::string enginePath =
#if defined(WIN32)
		"enginepath_win32"
#elif defined(__linux__) || defined (__FreeBSD__)
		"enginepath_linux"
#elif defined(__APPLE__)
		"enginepath_macos"
#else
#error "unknown platform"
#endif
	;

	if (!_name.empty()) 
	{
		// Import the game file into the registry
		GlobalRegistry().import(fullPath, "", Registry::treeStandard);

		// Get the engine path
		_enginePath = getKeyValue(enginePath);
	}
}

Game::Game(const Game& other) :
	IGame(other),
	_enginePath(other._enginePath),
	_name(other._name)
{}

std::string Game::getName() const
{
	return _name;
}

std::string Game::getXPathRoot() const
{
	return std::string("//game[@name='") + _name + "']";
}

std::string Game::getKeyValue(const std::string& key) const
{
    if (xml::NodeList found = GlobalRegistry().findXPath(getXPathRoot()); !found.empty()) {
        return found[0].getAttributeValue(key);
    }
    else {
        rError() << "Game: Keyvalue '" << key << "' not found for game type '" << _name << "'"
                 << std::endl;
        return "";
    }
}

bool Game::hasFeature(const std::string& feature) const
{
    xml::NodeList nodes = getLocalXPath("/features");
    if (nodes.empty())
        return false;

    // Find the first available feature which matches the query feature
    xml::NodeList features = nodes[0].getNamedChildren("feature");
    for (const auto& f: features) {
        if (f.getContent() == feature)
            return true;
    }

    // Nothing found, so the optional feature isn't present
    return false;
}

xml::NodeList Game::getLocalXPath(const std::string& localPath) const
{
    std::string absolutePath = getXPathRoot() + localPath;
    return GlobalRegistry().findXPath(absolutePath);
}

} // namespace game