/
ParticleLoader.cpp
93 lines (76 loc) · 2.35 KB
/
ParticleLoader.cpp
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
#include "ParticleLoader.h"
#include "ifilesystem.h"
#include "itextstream.h"
#include "debugging/ScopedDebugTimer.h"
namespace particles
{
void ParticleLoader::parseParticleDef(parser::DefTokeniser& tok, const std::string& filename)
{
// Standard DEF, starts with "particle <name> {"
auto declName = tok.nextToken();
// Check for a valid particle declaration, some .prt files contain materials
if (declName != "particle")
{
// No particle, skip name plus whole block
tok.skipTokens(1);
tok.assertNextToken("{");
for (std::size_t level = 1; level > 0;)
{
std::string token = tok.nextToken();
if (token == "}")
{
level--;
}
else if (token == "{")
{
level++;
}
}
return;
}
// Valid particle declaration, go ahead parsing the name
auto name = tok.nextToken();
tok.assertNextToken("{");
// Find the particle def (use the non-blocking, internal lookup)
auto def = _findOrInsert(name);
def->setFilename(filename);
// Let the particle construct itself from the token stream
def->parseFromTokens(tok);
}
void ParticleLoader::parseStream(std::istream& contents, const std::string& filename)
{
// Usual ritual, get a parser::DefTokeniser and start tokenising the DEFs
parser::BasicDefTokeniser<std::istream> tok(contents);
while (tok.hasMoreTokens())
{
parseParticleDef(tok, filename);
}
}
void ParticleLoader::load()
{
ScopedDebugTimer timer("Particle definitions parsed: ");
loadFiles([&](const vfs::FileInfo& fileInfo)
{
// Attempt to open the file in text mode
auto file = GlobalFileSystem().openTextFile(PARTICLES_DIR + fileInfo.name);
if (file)
{
// File is open, so parse the tokens
try
{
std::istream is(&(file->getInputStream()));
parseStream(is, fileInfo.name);
}
catch (parser::ParseException& e)
{
rError() << "[particles] Failed to parse " << fileInfo.name
<< ": " << e.what() << std::endl;
}
}
else
{
rError() << "[particles] Unable to open " << fileInfo.name << std::endl;
}
});
}
}