This commit is contained in:
Joshua Ashton 2023-01-18 10:16:34 +00:00
parent 1f17ee7fbb
commit 11d3111ec1
7 changed files with 174 additions and 29 deletions

View File

@ -68,6 +68,11 @@ namespace orange::stream
return Consume(first, end, " \t"); return Consume(first, end, " \t");
} }
inline size_t ConsumeSpaceAndNewLine(const char*& first, const char* end)
{
return Consume(first, end, " \t\r\n");
}
template <typename OutArray = SmallVector<char, 1>> template <typename OutArray = SmallVector<char, 1>>
size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr) size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr)
{ {
@ -118,4 +123,18 @@ namespace orange::stream
return true; return true;
} }
inline bool IsCPPComment(StringView fullRange, const char* first)
{
if (*first != '/')
return false;
if (fullRange.end() == first + 1)
return false;
if (*(first + 1) != '/')
return false;
return true;
}
} }

View File

@ -3,6 +3,7 @@
#include <Orange/Core/Types.h> #include <Orange/Core/Types.h>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <iostream>
namespace orange namespace orange
{ {
@ -80,6 +81,13 @@ namespace orange
: Span<const char>{str, strlen(str)} {} : Span<const char>{str, strlen(str)} {}
}; };
inline std::ostream& operator << (std::ostream& os, StringView view)
{
for (size_t i = 0; i < view.size; i++)
os << view[i];
return os;
}
struct Buffer : public BufferView struct Buffer : public BufferView
{ {
using BufferView::BufferView; using BufferView::BufferView;

View File

@ -13,7 +13,7 @@ namespace orange
SmallVector() {} SmallVector() {}
SmallVector(size_t size) { resize(size); } SmallVector(size_t size) { resize(size); }
SmallVector(Span<T> span) SmallVector(Span<const T> span)
{ {
reserve(span.size); reserve(span.size);
for (const auto& val : span) for (const auto& val : span)
@ -38,6 +38,7 @@ namespace orange
reserve(x.size()); reserve(x.size());
for (const auto& val : x) for (const auto& val : x)
push_back(val); push_back(val);
return *this;
} }
~SmallVector() ~SmallVector()

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Orange/Core/Variant.h> #include <Orange/Core/Variant.h>
#include <Orange/Core/Vector.h>
#include <Orange/Core/Parse.h> #include <Orange/Core/Parse.h>
#include <Orange/Core/Span.h> #include <Orange/Core/Span.h>
#include <Orange/Graphics/Color.h> #include <Orange/Graphics/Color.h>
@ -33,10 +34,12 @@ namespace orange::kv
class KeyValues; class KeyValues;
class KeyValuesVariant class KeyValuesVariant
{ {
public: public:
using KeyValuesChild = std::unique_ptr<KeyValues>; using KeyValuesChild = std::unique_ptr<KeyValues>;
using KeyValuesString = SmallVector<char, 8>;
KeyValuesVariant() KeyValuesVariant()
{ {
@ -64,7 +67,7 @@ namespace orange::kv
switch (m_type) switch (m_type)
{ {
case Types::String: case Types::String:
m_data.Destruct<std::string>(); m_str.clear();
break; break;
case Types::KeyValues: case Types::KeyValues:
m_data.Destruct<KeyValuesChild>(); m_data.Destruct<KeyValuesChild>();
@ -76,19 +79,11 @@ namespace orange::kv
m_data.Clear(); m_data.Clear();
} }
std::string GetString() const template <typename T>
{ T Get() const;
switch (m_type)
{
case Types::String:
return m_data.Get<std::string>();
default:
return "";
}
}
void Set(const std::string& val) { Clear(); m_type = Types::String; m_data.Construct<std::string>(val); } void Set(const std::string& val) { Clear(); m_type = Types::String; m_str = KeyValuesString{ StringView{ val } }; }
void Set(StringView val) { Clear(); m_type = Types::String; m_data.Construct<std::string>(val.data, val.data + val.size); } void Set(StringView val) { Clear(); m_type = Types::String; m_str = KeyValuesString{ val }; }
void Set(int32_t val) { Clear(); m_type = Types::Int; m_data.Get<int64_t>() = val; } void Set(int32_t val) { Clear(); m_type = Types::Int; m_data.Get<int64_t>() = val; }
void Set(int64_t val) { Clear(); m_type = Types::Int; m_data.Get<int64_t>() = val; } void Set(int64_t val) { Clear(); m_type = Types::Int; m_data.Get<int64_t>() = val; }
void Set(float val) { Clear(); m_type = Types::Float; m_data.Get<double>() = val; } void Set(float val) { Clear(); m_type = Types::Float; m_data.Get<double>() = val; }
@ -98,11 +93,20 @@ namespace orange::kv
void Set(uint32_t val) { Clear(); m_type = Types::Uint64; m_data.Get<uint64_t>() = val; } void Set(uint32_t val) { Clear(); m_type = Types::Uint64; m_data.Get<uint64_t>() = val; }
void Set(uint64_t val) { Clear(); m_type = Types::Uint64; m_data.Get<uint64_t>() = val; } void Set(uint64_t val) { Clear(); m_type = Types::Uint64; m_data.Get<uint64_t>() = val; }
void Set(KeyValuesChild val) { Clear(); m_type = Types::KeyValues; m_data.Get<KeyValuesChild>() = Move(val); } void Set(KeyValuesChild val) { Clear(); m_type = Types::KeyValues; m_data.Get<KeyValuesChild>() = Move(val); }
KeyValuesVariant& operator [](const char *string);
const KeyValuesVariant& operator [](const char *string) const;
static KeyValuesVariant& GetEmptyValue() { return s_Nothing; }
private: private:
static KeyValuesVariant s_Nothing;
KeyValuesType m_type = Types::None; KeyValuesType m_type = Types::None;
KeyValuesString m_str;
Variant< Variant<
std::string,
int64_t, int64_t,
double, double,
void*, void*,
@ -120,7 +124,38 @@ namespace orange::kv
const char *end = buffer.end(); const char *end = buffer.end();
return ParseChild(start, end); return ParseChild(start, end);
} }
static KeyValues& Nothing()
{
return s_Nothing;
}
KeyValuesVariant& operator [](const char *string)
{
auto iter = m_children.find(string);
if (iter == m_children.end())
{
std::cerr << "Returning KeyValuesVariant empty value: " << string << std::endl;
return KeyValuesVariant::GetEmptyValue();
}
return iter->second;
}
const KeyValuesVariant& operator [] (const char *string) const
{
auto iter = m_children.find(string);
if (iter == m_children.end())
{
std::cerr << "Returning KeyValuesVariant empty value: " << string << std::endl;
return KeyValuesVariant::GetEmptyValue();
}
return iter->second;
}
private: private:
static KeyValues s_Nothing;
static std::unique_ptr<KeyValues> ParseChild(const char*& start, const char* end) static std::unique_ptr<KeyValues> ParseChild(const char*& start, const char* end)
{ {
StringView range = StringView(start, end); StringView range = StringView(start, end);
@ -128,12 +163,12 @@ namespace orange::kv
if (start == end) if (start == end)
return nullptr; return nullptr;
stream::ConsumeSpace(start, end); stream::ConsumeSpaceAndNewLine(start, end);
if (*start != '{') if (*start != '{')
return nullptr; return nullptr;
auto kv = std::unique_ptr<KeyValues>(); auto kv = std::make_unique<KeyValues>();
bool inString = false; bool inString = false;
@ -141,21 +176,31 @@ namespace orange::kv
std::string key; std::string key;
std::string value; std::string value;
start++;
while (start != end) while (start != end)
{ {
start++;
if (stream::IsStringToken(range, start)) if (stream::IsStringToken(range, start))
{
inString = !inString; inString = !inString;
start++;
continue;
}
if (!inString) if (!inString)
{ {
if (*start == '\r') if (stream::IsCPPComment(range, start))
{
stream::AdvancePast(start, end, "\r\n");
stream::ConsumeSpaceAndNewLine(start, end);
continue; continue;
}
if (*start == '{') if (*start == '{')
{ {
fprintf(stdout, "Adding block child: %s - {\n", key.c_str());
auto child = ParseChild(start, end); auto child = ParseChild(start, end);
kv->m_children.emplace(key, Move(child)); kv->m_children.emplace(key, Move(child));
fprintf(stdout, "Adding block child: }\n");
fillingInValue = false; fillingInValue = false;
key.clear(); key.clear();
@ -168,30 +213,33 @@ namespace orange::kv
break; break;
} }
if (*start == ' ' || *start == '\t' || *start == '\n') if (*start == ' ' || *start == '\t' || *start == '\n' || *start == '\r')
{ {
fillingInValue = !fillingInValue;
if (!fillingInValue) if (!fillingInValue)
{ {
fillingInValue = true; fprintf(stdout, "Adding child: %s - %s\n", key.c_str(), value.c_str());
}
else
{
kv->m_children.emplace(key, value); kv->m_children.emplace(key, value);
fillingInValue = false;
key.clear(); key.clear();
value.clear(); value.clear();
} }
else if (*start == '\n' || *start == '\r')
{
fillingInValue = false;
}
stream::ConsumeSpace(start, end); stream::ConsumeSpaceAndNewLine(start, end);
continue; continue;
} }
} }
if (fillingInValue) if (fillingInValue)
value += *start; value.push_back(*start);
else else
key += *start; key.push_back(*start);
start++;
} }
return kv; return kv;
@ -199,4 +247,49 @@ namespace orange::kv
std::unordered_multimap<std::string, KeyValuesVariant> m_children; std::unordered_multimap<std::string, KeyValuesVariant> m_children;
}; };
template <>
inline StringView KeyValuesVariant::Get() const
{
switch (m_type)
{
case Types::String:
return m_str;
default:
return "";
}
}
template <>
inline KeyValues& KeyValuesVariant::Get() const
{
switch (m_type)
{
case Types::KeyValues:
{
auto value = m_data.Get<KeyValuesChild>().get();
if (value)
return *value;
}
[[fallthrough]];
default:
return KeyValues::Nothing();
}
}
inline KeyValuesVariant& KeyValuesVariant::operator [](const char *string)
{
if (m_type != Types::KeyValues)
abort();
return Get<kv::KeyValues&>()[string];
}
inline const KeyValuesVariant& KeyValuesVariant::operator [](const char *string) const
{
if (m_type != Types::KeyValues)
abort();
return Get<const kv::KeyValues&>()[string];
}
} }

View File

@ -283,6 +283,21 @@ int main(int argc, char** argv)
std::cout << std::endl; std::cout << std::endl;
#endif #endif
auto r_vmf = fs::OpenFileIntoTextBuffer("/home/joshua/Code/Desolation/game/sdk_content/maps/hl2_sdk/sdk_phys_constraint.vmf");
auto r_vmfkv = kv::KeyValues::ParseFromUTF8(*r_vmf);
if (!r_vmfkv)
{
fprintf(stderr, "Parsing VMF failed!\n");
return 1;
}
kv::KeyValues &vmfkv = *r_vmfkv;
std::cout << "editorversion: " << vmfkv["versioninfo"]["editorversion"].Get<StringView>() << std::endl;
auto newVertexSlice = *pooler.AllocSlice(sizeof(StaticVertex) * r_mesh->vertexData.VertexCount(), sizeof(StaticVertex)); auto newVertexSlice = *pooler.AllocSlice(sizeof(StaticVertex) * r_mesh->vertexData.VertexCount(), sizeof(StaticVertex));
auto newIndexSlice = *pooler.AllocSlice(sizeof(IndexType) * r_mesh->indices.size(), sizeof(IndexType)); auto newIndexSlice = *pooler.AllocSlice(sizeof(IndexType) * r_mesh->indices.size(), sizeof(IndexType));
r_mesh->vertexData.GetStaticVertices().copy((uint8_t*)(r_buffer->ptr) + newVertexSlice.offset); r_mesh->vertexData.GetStaticVertices().copy((uint8_t*)(r_buffer->ptr) + newVertexSlice.offset);

View File

@ -0,0 +1,7 @@
#include <Orange/Formats/KeyValues.h>
namespace orange::kv
{
KeyValuesVariant KeyValuesVariant::s_Nothing;
KeyValues KeyValues::s_Nothing;
}

View File

@ -11,6 +11,8 @@ orange_src = files([
'Core/Filesystem.cpp', 'Core/Filesystem.cpp',
'Core/Log.cpp', 'Core/Log.cpp',
'Formats/KeyValues.cpp',
'Graphics/Mesh.cpp', 'Graphics/Mesh.cpp',
'Render/Input.cpp', 'Render/Input.cpp',