KV work
This commit is contained in:
parent
1f17ee7fbb
commit
11d3111ec1
|
@ -68,6 +68,11 @@ namespace orange::stream
|
|||
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>>
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <Orange/Core/Types.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
|
@ -80,6 +81,13 @@ namespace orange
|
|||
: 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
|
||||
{
|
||||
using BufferView::BufferView;
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace orange
|
|||
|
||||
SmallVector() {}
|
||||
SmallVector(size_t size) { resize(size); }
|
||||
SmallVector(Span<T> span)
|
||||
SmallVector(Span<const T> span)
|
||||
{
|
||||
reserve(span.size);
|
||||
for (const auto& val : span)
|
||||
|
@ -38,6 +38,7 @@ namespace orange
|
|||
reserve(x.size());
|
||||
for (const auto& val : x)
|
||||
push_back(val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SmallVector()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Core/Variant.h>
|
||||
#include <Orange/Core/Vector.h>
|
||||
#include <Orange/Core/Parse.h>
|
||||
#include <Orange/Core/Span.h>
|
||||
#include <Orange/Graphics/Color.h>
|
||||
|
@ -33,10 +34,12 @@ namespace orange::kv
|
|||
|
||||
class KeyValues;
|
||||
|
||||
|
||||
class KeyValuesVariant
|
||||
{
|
||||
public:
|
||||
using KeyValuesChild = std::unique_ptr<KeyValues>;
|
||||
using KeyValuesString = SmallVector<char, 8>;
|
||||
|
||||
KeyValuesVariant()
|
||||
{
|
||||
|
@ -64,7 +67,7 @@ namespace orange::kv
|
|||
switch (m_type)
|
||||
{
|
||||
case Types::String:
|
||||
m_data.Destruct<std::string>();
|
||||
m_str.clear();
|
||||
break;
|
||||
case Types::KeyValues:
|
||||
m_data.Destruct<KeyValuesChild>();
|
||||
|
@ -76,19 +79,11 @@ namespace orange::kv
|
|||
m_data.Clear();
|
||||
}
|
||||
|
||||
std::string GetString() const
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Types::String:
|
||||
return m_data.Get<std::string>();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
T Get() const;
|
||||
|
||||
void Set(const std::string& val) { Clear(); m_type = Types::String; m_data.Construct<std::string>(val); }
|
||||
void Set(StringView val) { Clear(); m_type = Types::String; m_data.Construct<std::string>(val.data, val.data + val.size); }
|
||||
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_str = KeyValuesString{ 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(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(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); }
|
||||
|
||||
KeyValuesVariant& operator [](const char *string);
|
||||
|
||||
const KeyValuesVariant& operator [](const char *string) const;
|
||||
|
||||
static KeyValuesVariant& GetEmptyValue() { return s_Nothing; }
|
||||
private:
|
||||
static KeyValuesVariant s_Nothing;
|
||||
|
||||
KeyValuesType m_type = Types::None;
|
||||
|
||||
KeyValuesString m_str;
|
||||
|
||||
Variant<
|
||||
std::string,
|
||||
int64_t,
|
||||
double,
|
||||
void*,
|
||||
|
@ -120,7 +124,38 @@ namespace orange::kv
|
|||
const char *end = buffer.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:
|
||||
static KeyValues s_Nothing;
|
||||
|
||||
static std::unique_ptr<KeyValues> ParseChild(const char*& start, const char* end)
|
||||
{
|
||||
StringView range = StringView(start, end);
|
||||
|
@ -128,12 +163,12 @@ namespace orange::kv
|
|||
if (start == end)
|
||||
return nullptr;
|
||||
|
||||
stream::ConsumeSpace(start, end);
|
||||
stream::ConsumeSpaceAndNewLine(start, end);
|
||||
|
||||
if (*start != '{')
|
||||
return nullptr;
|
||||
|
||||
auto kv = std::unique_ptr<KeyValues>();
|
||||
auto kv = std::make_unique<KeyValues>();
|
||||
|
||||
bool inString = false;
|
||||
|
||||
|
@ -141,21 +176,31 @@ namespace orange::kv
|
|||
std::string key;
|
||||
std::string value;
|
||||
|
||||
start++;
|
||||
while (start != end)
|
||||
{
|
||||
start++;
|
||||
if (stream::IsStringToken(range, start))
|
||||
{
|
||||
inString = !inString;
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!inString)
|
||||
{
|
||||
if (*start == '\r')
|
||||
if (stream::IsCPPComment(range, start))
|
||||
{
|
||||
stream::AdvancePast(start, end, "\r\n");
|
||||
stream::ConsumeSpaceAndNewLine(start, end);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*start == '{')
|
||||
{
|
||||
fprintf(stdout, "Adding block child: %s - {\n", key.c_str());
|
||||
auto child = ParseChild(start, end);
|
||||
kv->m_children.emplace(key, Move(child));
|
||||
fprintf(stdout, "Adding block child: }\n");
|
||||
|
||||
fillingInValue = false;
|
||||
key.clear();
|
||||
|
@ -168,30 +213,33 @@ namespace orange::kv
|
|||
break;
|
||||
}
|
||||
|
||||
if (*start == ' ' || *start == '\t' || *start == '\n')
|
||||
if (*start == ' ' || *start == '\t' || *start == '\n' || *start == '\r')
|
||||
{
|
||||
fillingInValue = !fillingInValue;
|
||||
|
||||
if (!fillingInValue)
|
||||
{
|
||||
fillingInValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stdout, "Adding child: %s - %s\n", key.c_str(), value.c_str());
|
||||
kv->m_children.emplace(key, value);
|
||||
|
||||
fillingInValue = false;
|
||||
key.clear();
|
||||
value.clear();
|
||||
}
|
||||
else if (*start == '\n' || *start == '\r')
|
||||
{
|
||||
fillingInValue = false;
|
||||
}
|
||||
|
||||
stream::ConsumeSpace(start, end);
|
||||
stream::ConsumeSpaceAndNewLine(start, end);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillingInValue)
|
||||
value += *start;
|
||||
value.push_back(*start);
|
||||
else
|
||||
key += *start;
|
||||
key.push_back(*start);
|
||||
|
||||
start++;
|
||||
}
|
||||
|
||||
return kv;
|
||||
|
@ -199,4 +247,49 @@ namespace orange::kv
|
|||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -283,6 +283,21 @@ int main(int argc, char** argv)
|
|||
std::cout << std::endl;
|
||||
#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 newIndexSlice = *pooler.AllocSlice(sizeof(IndexType) * r_mesh->indices.size(), sizeof(IndexType));
|
||||
r_mesh->vertexData.GetStaticVertices().copy((uint8_t*)(r_buffer->ptr) + newVertexSlice.offset);
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#include <Orange/Formats/KeyValues.h>
|
||||
|
||||
namespace orange::kv
|
||||
{
|
||||
KeyValuesVariant KeyValuesVariant::s_Nothing;
|
||||
KeyValues KeyValues::s_Nothing;
|
||||
}
|
|
@ -11,6 +11,8 @@ orange_src = files([
|
|||
'Core/Filesystem.cpp',
|
||||
'Core/Log.cpp',
|
||||
|
||||
'Formats/KeyValues.cpp',
|
||||
|
||||
'Graphics/Mesh.cpp',
|
||||
|
||||
'Render/Input.cpp',
|
||||
|
|
Loading…
Reference in New Issue