Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
GenericFileFormat.h
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2022 Petr Ohlidal
4
5 For more information, see http://www.rigsofrods.org/
6
7 Rigs of Rods is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 3, as
9 published by the Free Software Foundation.
10
11 Rigs of Rods is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
18*/
19
33
34#pragma once
35
36#include "RefCountingObject.h"
38#include "BitFlags.h"
39#include "Application.h"
40
41#include <vector>
42#include <string>
43
44#include <Ogre.h>
45
46namespace RoR {
47
48enum class TokenType
49{
50 NONE,
51 LINEBREAK, // Input: LF (CR is ignored); Output: platform-specific.
52 COMMENT, // Line starting with ; (skipping whitespace). Data: offset in string pool.
53 STRING, // Quoted string. Data: offset in string pool.
54 FLOAT,
55 INT,
56 BOOL, // Lowercase 'true'/'false'. Data: 1.0 for true, 0.0 for false.
57 KEYWORD, // Unquoted string at start of line (skipping whitespace). Data: offset in string pool.
58};
59
60struct Token
61{
63 float data;
64};
65
66struct GenericDocument: public RefCountingObject<GenericDocument>
67{
76
77 virtual ~GenericDocument() {};
78
79 std::vector<char> string_pool; // Data of COMMENT/KEYWORD/STRING tokens; NUL-terminated strings.
80 std::vector<Token> tokens;
81
82 virtual void loadFromDataStream(Ogre::DataStreamPtr datastream, BitMask_t options = 0);
83 virtual void saveToDataStream(Ogre::DataStreamPtr datastream);
84
85 virtual bool loadFromResource(std::string resource_name, std::string resource_group_name, BitMask_t options = 0);
86 virtual bool saveToResource(std::string resource_name, std::string resource_group_name);
87};
88
89struct GenericDocContext: public RefCountingObject<GenericDocContext>
90{
92 {
93 ROR_ASSERT(doc != nullptr);
94 if (doc == nullptr && AngelScript::asGetActiveContext() != nullptr)
95 {
96 AngelScript::asGetActiveContext()->SetException("Cannot create GenericDocContextClass from null GenericDocument!");
97 }
98 }
99 virtual ~GenericDocContext() {};
100
102 uint32_t token_pos = 0;
103
104 // PLEASE maintain the same order as in 'bindings/GenericFileFormatAngelscript.cpp' and 'doc/*/GenericDocContextClass.h'
105
106 bool moveNext() { token_pos++; return endOfFile(); }
107 uint32_t getPos() const { return token_pos; }
108 bool seekNextLine();
109 int countLineArgs();
110 bool endOfFile(int offset = 0) const { return token_pos + offset >= doc->tokens.size(); }
111 TokenType tokenType(int offset = 0) const { return !endOfFile(offset) ? doc->tokens[token_pos + offset].type : TokenType::NONE; }
112
113 std::string getTokString(int offset = 0) const { ROR_ASSERT(isTokString(offset)); return getStringData(offset); }
114 float getTokFloat(int offset = 0) const { ROR_ASSERT(isTokFloat(offset)); return getFloatData(offset); }
115 int getTokInt(int offset = 0) const { ROR_ASSERT(isTokInt(offset)); return (int)getFloatData(offset); }
116 float getTokNumeric(int offset = 0) const { ROR_ASSERT(isTokNumeric(offset)); return getFloatData(offset); }
117 bool getTokBool(int offset = 0) const { ROR_ASSERT(isTokBool(offset)); return getFloatData(offset) == 1.f; }
118 std::string getTokKeyword(int offset = 0) const { ROR_ASSERT(isTokKeyword(offset)); return getStringData(offset); }
119 std::string getTokComment(int offset = 0) const { ROR_ASSERT(isTokComment(offset)); return getStringData(offset); }
120
121 bool isTokString(int offset = 0) const { return tokenType(offset) == TokenType::STRING; }
122 bool isTokFloat(int offset = 0) const { return tokenType(offset) == TokenType::FLOAT; }
123 bool isTokInt(int offset = 0) const { return tokenType(offset) == TokenType::INT; }
124 bool isTokBool(int offset = 0) const { return tokenType(offset) == TokenType::BOOL; }
125 bool isTokKeyword(int offset = 0) const { return tokenType(offset) == TokenType::KEYWORD; }
126 bool isTokComment(int offset = 0) const { return tokenType(offset) == TokenType::COMMENT; }
127 bool isTokLineBreak(int offset = 0) const { return tokenType(offset) == TokenType::LINEBREAK; }
128 bool isTokNumeric(int offset = 0) const { return isTokInt(offset) || isTokFloat(offset); }
129
130 // Editing functions:
131
132 void appendTokens(int count);
133 bool insertToken(int offset = 0);
134 bool eraseToken(int offset = 0);
135
136 void appendTokString(const std::string& str) { appendTokens(1); setTokString(0, str); }
137 void appendTokFloat(float val) { appendTokens(1); setTokFloat(0, val); }
138 void appendTokInt(int val) { appendTokens(1); setTokInt(0, val); }
139 void appendTokBool(bool val) { appendTokens(1); setTokBool(0, val); }
140 void appendTokKeyword(const std::string& str) { appendTokens(1); setTokKeyword(0, str); }
141 void appendTokComment(const std::string& str) { appendTokens(1); setTokComment(0, str); }
143
144 bool setTokString(int offset, const std::string& str) { return setStringData(offset, TokenType::STRING, str); }
145 bool setTokFloat(int offset, float val) { return setFloatData(offset, TokenType::FLOAT, val); }
146 bool setTokInt(int offset, int val) { return setFloatData(offset, TokenType::INT, val); }
147 bool setTokBool(int offset, bool val) { return setFloatData(offset, TokenType::BOOL, val); }
148 bool setTokKeyword(int offset, const std::string& str) { return setStringData(offset, TokenType::KEYWORD, str); }
149 bool setTokComment(int offset, const std::string& str) { return setStringData(offset, TokenType::COMMENT, str); }
150 bool setTokLineBreak(int offset) { return setFloatData(offset, TokenType::LINEBREAK, 0.f); }
151
152 // Not exported to script:
153
154 const char* getStringData(int offset = 0) const { return !endOfFile(offset) ? (doc->string_pool.data() + (uint32_t)doc->tokens[token_pos + offset].data) : ""; }
155 float getFloatData(int offset = 0) const { return !endOfFile(offset) ? doc->tokens[token_pos + offset].data : 0.f; }
156 bool setStringData(int offset, TokenType type, const std::string& data);
157 bool setFloatData(int offset, TokenType type, float data);
158};
159
160} // namespace RoR
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
Bit operations.
#define BITMASK(OFFSET)
Definition BitFlags.h:10
uint32_t BitMask_t
Definition BitFlags.h:7
Self reference-counting objects, as requred by AngelScript garbage collector.
void appendTokens(int count)
Appends a series of TokenType::NONE and sets Pos at the first one added; use setTok* functions to fil...
float getTokNumeric(int offset=0) const
bool setTokLineBreak(int offset)
bool isTokBool(int offset=0) const
bool getTokBool(int offset=0) const
bool setFloatData(int offset, TokenType type, float data)
bool isTokKeyword(int offset=0) const
std::string getTokKeyword(int offset=0) const
bool setStringData(int offset, TokenType type, const std::string &data)
void appendTokKeyword(const std::string &str)
float getTokFloat(int offset=0) const
bool setTokKeyword(int offset, const std::string &str)
bool isTokNumeric(int offset=0) const
GenericDocContext(GenericDocumentPtr d)
bool insertToken(int offset=0)
Inserts TokenType::NONE;.
bool setTokInt(int offset, int val)
void appendTokFloat(float val)
bool setTokComment(int offset, const std::string &str)
bool eraseToken(int offset=0)
bool endOfFile(int offset=0) const
bool isTokLineBreak(int offset=0) const
std::string getTokString(int offset=0) const
bool isTokComment(int offset=0) const
bool isTokString(int offset=0) const
bool setTokBool(int offset, bool val)
bool isTokInt(int offset=0) const
int getTokInt(int offset=0) const
float getFloatData(int offset=0) const
bool isTokFloat(int offset=0) const
void appendTokString(const std::string &str)
bool setTokString(int offset, const std::string &str)
std::string getTokComment(int offset=0) const
void appendTokComment(const std::string &str)
const char * getStringData(int offset=0) const
TokenType tokenType(int offset=0) const
bool setTokFloat(int offset, float val)
static const BitMask_t OPTION_ALLOW_SLASH_COMMENTS
Allow comments starting with //.
std::vector< char > string_pool
static const BitMask_t OPTION_ALLOW_SEPARATOR_COLON
Allow ':' as separator between tokens.
virtual bool saveToResource(std::string resource_name, std::string resource_group_name)
virtual void loadFromDataStream(Ogre::DataStreamPtr datastream, BitMask_t options=0)
virtual void saveToDataStream(Ogre::DataStreamPtr datastream)
virtual bool loadFromResource(std::string resource_name, std::string resource_group_name, BitMask_t options=0)
static const BitMask_t OPTION_FIRST_LINE_IS_TITLE
First non-empty & non-comment line is a naked string with spaces.
static const BitMask_t OPTION_ALLOW_NAKED_STRINGS
Allow strings without quotes, for backwards compatibility.
static const BitMask_t OPTION_ALLOW_SEPARATOR_EQUALS
Allow '=' as separator between tokens.
std::vector< Token > tokens
static const BitMask_t OPTION_ALLOW_HASH_COMMENTS
Allow comments starting with #.
static const BitMask_t OPTION_ALLOW_BRACED_KEYWORDS
Allow INI-like '[keyword]' tokens.
static const BitMask_t OPTION_PARENTHESES_CAPTURE_SPACES
If non-empty NAKED string encounters '(', following spaces will be captured until matching ')' is fou...