File: Component.h

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 (272 lines) | stat: -rw-r--r-- 6,260 bytes parent folder | download | duplicates (5)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#pragma once

#include "SpecifierType.h"
#include "Specifier.h"
#include "ComponentType.h"

#include <cassert>
#include <vector>
#include <string>
#include "string/join.h"
#include <sigc++/signal.h>

namespace objectives
{

/**
 * A component of an objective.
 *
 * Each objective may have a number of components, which are combined using
 * boolean operations to determine whether the objective is satisfied or not.
 * A component is essentially a condition which needs to be met in order to
 * satisfy the overall objective.
 */
class Component
{
private:
	// Completion state flag
	bool _satisfied;

	// Inverted flag
	bool _inverted;

	// Irreversible (latched) flag
	bool _irreversible;

	// Player responsible flag
	bool _playerResponsible;

	// The clock interval in seconds (only applicable for clocked components)
	// is negative if not used
	float _clockInterval;

	// Component type
	ComponentType _type;

    // List of Specifiers (SpecifierType + value pairs)
    SpecifierList _specifiers;

	/**
	 * greebo: Each component can have an arbitrary number of arguments.
	 */
	typedef std::vector<std::string> ArgumentList;
	ArgumentList _arguments;

	sigc::signal<void> _sigChanged;

public:

	/**
	 * Construct a Component with default settings.
	 *
	 * All flags are set to false, and the type is set to an arbitrary value.
	 */
	Component()
	: _satisfied(false),
	  _inverted(false),
	  _irreversible(false),
	  _playerResponsible(false),
	  _clockInterval(-1.0f),
	  _type(ComponentType::COMP_KILL()), // arbitrary choice, no NONE option
      _specifiers(static_cast<std::size_t>(Specifier::MAX_SPECIFIERS))
	{ }

	// Copy-constructor
	Component(const Component& other) : 
		_satisfied(other._satisfied),
		_inverted(other._inverted),
		_irreversible(other._irreversible),
		_playerResponsible(other._playerResponsible),
		_clockInterval(other._clockInterval),
		_type(other._type),
		_specifiers(other._specifiers),
		_arguments(other._arguments)
		// don't copy signals
	{ }

	/**
	 * Set the flag to indicate that this component has been satisfied.
	 */
	void setSatisfied(bool satisfied) {
		_satisfied = satisfied;
		_sigChanged();
	}

	/**
	 * Get the satisfied status flag.
	 */
	bool isSatisfied() const {
		return _satisfied;
	}

	/**
	 * Set the flag to indicate that the sense of this component is inverted.
	 *
	 * If true, this component is logically <b>NOT</b>ed, so when the conditions
	 * described by the type and specifiers are not met, the component state is
	 * true, and when they are met, it is false.
	 */
	void setInverted(bool inverted) {
		_inverted = inverted;
		_sigChanged();
	}

	/**
	 * Get the inverted status.
	 */
	bool isInverted() const {
		return _inverted;
	}

	/**
	 * Set the flag to indicate that this component changes state once then
	 * latches, even if its in-game condition is no longer satisfied.
	 */
	void setIrreversible(bool irreversible) {
		_irreversible = irreversible;
		_sigChanged();
	}

	/**
	 * Get the irreversible status.
	 */
	bool isIrreversible() const {
		return _irreversible;
	}

	/**
	 * Set the flag to indicate that the player must be responsible for
	 * satisfying this component.
	 *
	 * If this flag is set, the component will not be satisfied by an event
	 * which is not <i>directly</i> caused by the player. For example, if the
	 * component requires the killing of an AI, it will not be satisfied if the
	 * AI is killed by another AI rather than the player.
	 */
	void setPlayerResponsible(bool playerResponsible) {
		_playerResponsible = playerResponsible;
		_sigChanged();
	}

    /**
     * Get the player-responsible status.
     */
    bool isPlayerResponsible() const {
        return _playerResponsible;
    }

	/**
     * Set the clock interval for clocked components in seconds.
     */
	void setClockInterval(float clockInterval) {
		_clockInterval = clockInterval;
		_sigChanged();
	}

	/**
     * Get the clock interval for clocked components in seconds.
	 * Returns negative values if this option is not used for this component.
     */
	float getClockInterval() const {
		return _clockInterval;
	}

	/**
	 * Set the type of this component ("kill", "ko" etc).
	 */
	void setType(ComponentType type) {
		_type = type;
		_sigChanged();
	}

	/**
	 * Get the component type.
	 */
	ComponentType getType() const {
		return _type;
	}

	/**
	 * Return a string description of this Component.
	 */
	std::string getString();

    /**
     * Set the Specifier at the given index.
     *
     * @param idx
     * The index of the specifier, starting from 1.
     */
    void setSpecifier(Specifier::SpecifierNumber num, SpecifierPtr spec)
    {
        assert(
            _specifiers.size() == static_cast<std::size_t>(
                Specifier::MAX_SPECIFIERS
            )
        );
        _specifiers[static_cast<std::size_t>(num)] = spec;
		_sigChanged();
    }

    /**
     * Get the Specifier at the given index.
     *
     * @param idx
     * The index of the specifier, starting from 1.
     */
    SpecifierPtr getSpecifier(Specifier::SpecifierNumber num) const
    {
        assert(
            _specifiers.size() == static_cast<std::size_t>(
                Specifier::MAX_SPECIFIERS
            )
        );
        return _specifiers[static_cast<std::size_t>(num)];
    }

	void clearArguments() {
		_arguments.clear();
		_sigChanged();
	}

	void addArgument(const std::string& arg) {
		_arguments.push_back(arg);
		_sigChanged();
	}

	std::size_t getNumArguments() {
		return _arguments.size();
	}

	// returns "" if the argument with the given index doesn't exist
	std::string getArgument(std::size_t index) {
		return index < _arguments.size() ? _arguments[index] : "";
	}

	// Sets the argument with the given index
	void setArgument(std::size_t index, const std::string& value) {
		// Ensure that the vector is large enough
		if (_arguments.size() <= index) {
			_arguments.resize(index+1);
		}

		// Now set the value
		_arguments[index] = value;

		_sigChanged();
	}

	// Returns all arguments in a space-delimited string
	std::string getArgumentString() const
	{
		return string::join(_arguments, " ");
	}

	// Allow client code to be notified on change events
	sigc::signal<void> signal_Changed() const
	{
		return _sigChanged;
	}
};

}