/
ParticleDef.h
179 lines (137 loc) · 3.54 KB
/
ParticleDef.h
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
#pragma once
#include "StageDef.h"
#include "iparticles.h"
#include "parser/DefTokeniser.h"
#include "string/string.h"
#include <vector>
#include <set>
namespace particles
{
/**
* Representation of a single particle definition. Each definition is comprised
* of a number of "stages", which must all be rendered in turn.
*/
class ParticleDef
: public IParticleDef
{
// Name
std::string _name;
// The filename this particle has been defined in
std::string _filename;
// Depth hack
float _depthHack;
// Vector of stages
typedef std::vector<StageDefPtr> StageList;
StageList _stages;
// Changed signal
sigc::signal<void> _changedSignal;
// A unique parse pass identifier
std::size_t _parseStamp;
public:
/**
* Construct a named ParticleDef.
*/
ParticleDef(const std::string& name)
: _name(name)
{ }
/**
* Return the ParticleDef name.
*/
const std::string& getName() const override
{
return _name;
}
const std::string& getFilename() const override
{
return _filename;
}
void setFilename(const std::string& filename) override
{
_filename = filename;
}
// Clears stage and depth hack information
// Name and observers are NOT cleared
void clear()
{
_depthHack = false;
_stages.clear();
}
// IParticleDef implementation
sigc::signal<void>& signal_changed() override
{
return _changedSignal;
}
float getDepthHack() const override
{
return _depthHack;
}
void setDepthHack(float value) override
{
_depthHack = value;
}
std::size_t getNumStages() const override
{
return _stages.size();
}
const IStageDef& getStage(std::size_t stageNum) const override
{
return *_stages[stageNum];
}
IStageDef& getStage(std::size_t stageNum) override
{
return *_stages[stageNum];
}
std::size_t addParticleStage() override;
void removeParticleStage(std::size_t index) override;
void swapParticleStages(std::size_t index, std::size_t index2) override;
void appendStage(const StageDefPtr& stage);
bool operator==(const IParticleDef& other) const override
{
// Compare depth hack flag
if (getDepthHack() != other.getDepthHack()) return false;
// Compare number of stages
if (getNumStages() != other.getNumStages()) return false;
// Compare each stage
for (std::size_t i = 0; i < getNumStages(); ++i)
{
if (getStage(i) != other.getStage(i)) return false;
}
// All checks passed => equal
return true;
}
bool operator!=(const IParticleDef& other) const override
{
return !operator==(other);
}
void copyFrom(const IParticleDef& other) override;
void parseFromTokens(parser::DefTokeniser& tok);
std::size_t getParseStamp() const
{
return _parseStamp;
}
void setParseStamp(std::size_t stamp)
{
_parseStamp = stamp;
}
// Stream insertion operator, writing the entire particle def to the given stream
friend std::ostream& operator<< (std::ostream& stream, const ParticleDef& def);
};
typedef std::shared_ptr<ParticleDef> ParticleDefPtr;
// This will write the entire particle decl to the given stream, including the leading "particle" keyword
inline std::ostream& operator<<(std::ostream& stream, const ParticleDef& def)
{
// Don't use scientific notation when exporting floats
stream << std::fixed;
// Decl keyword, name and opening brace
stream << "particle " << def.getName() << " { " << std::endl;
// Write stages, one by one
for (ParticleDef::StageList::const_iterator i = def._stages.begin(); i != def._stages.end(); ++i)
{
const StageDef& stage = **i;
stream << stage;
}
// Closing brace
stream << "}";
return stream;
}
}