1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Implementações em ContentWriter

This commit is contained in:
Danilo 2024-08-07 15:23:31 -03:00
parent 61aa08ff61
commit db3258c777
9 changed files with 147 additions and 7 deletions

View File

@ -40,7 +40,7 @@ add_library (Xn65 STATIC
"platform-dx/audioengine.cpp"
"graphics/gresource.cpp"
"platform-dx/effect.cpp"
"exception.cpp" "platform-dx/screen.cpp" "pipeline/writer.cpp")
"exception.cpp" "platform-dx/screen.cpp" "pipeline/writer.cpp" "pipeline/compiler.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET Xn65 PROPERTY CXX_STANDARD 20)

View File

@ -0,0 +1,5 @@
#include "xna/pipeline/compiler.hpp"
namespace xna {
}

View File

@ -1,4 +1,5 @@
#include "xna/pipeline/writer.hpp"
#include "xna/pipeline/compiler.hpp"
namespace xna {
ContentWriter::ContentWriter(
@ -22,6 +23,34 @@ namespace xna {
OutStream = reinterpret_pointer_cast<Stream>(contentData);
}
P_ContentTypeWriter ContentWriter::GetTypeWriter(Type const& type, Int& typeIndex) {
const auto& hash = type.GetHashCode();
if (typeTable.contains(hash)) {
typeIndex = typeTable[hash];
return typeWriters[typeIndex];
}
std::vector<P_Type> dependecies;
auto typeWriter = compiler->GetTypeWriter(type, dependecies);
typeIndex = typeWriters.size();
typeWriters.push_back(typeWriter);
typeTable.emplace(type.GetHashCode(), typeIndex);
for (size_t i = 0; i < dependecies.size(); ++i) {
const auto& type1 = dependecies[i];
if (type1 != typeof<std::any>())
{
Int _;
GetTypeWriter(*type1, _);
}
}
return typeWriter;
}
void ContentWriter::WriteSharedResources() {
while (sharedResources.size() > 0) {
sharedResources.pop();

View File

@ -16,7 +16,7 @@ namespace xna {
constexpr bool IsPrimitive() const { return isPrimitive; }
constexpr bool IsPointer() const { return isPointer; }
size_t GetHashCode() const;
HashValue GetHashCode() const;
constexpr bool operator==(const Type& other) const {
return

View File

@ -20,6 +20,10 @@
#include "helpers.hpp"
namespace xna {
//
// Util types
//
using HashValue = size_t;
//
//C# nameof
@ -221,6 +225,7 @@ namespace xna {
using P_Stream = sptr<Stream>;
using P_MemoryStream = sptr<MemoryStream>;
using P_FileStream = sptr<FileStream>;
using P_Type = sptr<Type>;
//Pipeline
using P_ContentWriter = sptr<ContentWriter>;
using P_ContentCompiler = sptr<ContentCompiler>;

View File

@ -22,6 +22,9 @@ namespace xna {
static void ThrowIfNull(void const* argument, std::string const& argumentName, std::source_location const& location = std::source_location::current());
template <class T>
static void ThrowTIsNull(T const& value, std::source_location const& location = std::source_location::current());
inline static const std::string FAILED_TO_CREATE = "Failed to create component.";
inline static const std::string FAILED_TO_APPLY = "Failed to apply component.";
inline static const std::string FAILED_TO_MAKE_WINDOW_ASSOCIATION = "Failed to create association with window.";
@ -34,6 +37,15 @@ namespace xna {
inline static const std::string OUT_OF_BOUNDS = "Out of bounds.";
inline static const std::string END_OF_FILE = "End of file.";
};
template <class T>
static void Exception::ThrowTIsNull(T const& value, std::source_location const& location) {
if constexpr (XnaHelper::IsSmartPoint<T>()) {
if (value == nullptr) {
Exception::Throw(Exception::ARGUMENT_IS_NULL, location);
}
}
}
}
#endif

View File

@ -62,6 +62,15 @@ namespace xna {
else
Exception::Throw(Exception::UNABLE_TO_BUILD_OBJECT, location);
}
template <typename T>
static inline bool TIsNull(T const& value) {
if constexpr (IsSmartPoint<T>()) {
return value == nullptr;
}
return false;
}
};
}

View File

@ -5,7 +5,8 @@
namespace xna {
class ContentCompiler {
public:
P_ContentTypeWriter GetTypeWriter(Type const& type, std::vector<P_Type> dependencies);
};
}

View File

@ -6,17 +6,28 @@
#include "pipeline-enums.hpp"
#include "../common/numerics.hpp"
#include "../common/color.hpp"
#include "../csharp/type.hpp"
namespace xna {
class ContentTypeWriter {
public:
virtual String GetRuntimeReader(TargetPlatform targetPlatform) = 0;
virtual Int TypeVersion() const { return 0; }
virtual void Write(ContentWriter& output, Object& value);
};
template <class T>
class ContentTypeWriter_T : public ContentTypeWriter {
public:
template <typename T>
virtual void Write(ContentWriter& output, T& value);
};
template <class T>
class ExternalReference {
public:
String FileName() const;
};
//Provides an implementation for many of the ContentCompiler methods including compilation, state tracking for shared resources and creation of the header type manifest.
@ -73,7 +84,7 @@ namespace xna {
private:
template <class T> void InvokeWriter(T& value, ContentTypeWriter& writer);
sptr<ContentTypeWriter> GetTypeWriter(Type const& type, int& typeIndex) { return nullptr; }
P_ContentTypeWriter GetTypeWriter(Type const& type, Int& typeIndex);
void WriteSharedResources();
void WriteHeader();
void WriteFinalOutput();
@ -94,6 +105,7 @@ namespace xna {
std::vector<P_ContentTypeWriter> typeWriters;
std::map<std::any, Int> sharedResourceNames;
std::queue<std::any> sharedResources;
std::map<HashValue, Int> typeTable;
private:
static constexpr Ushort XnbVersion = 5;
@ -103,6 +115,7 @@ namespace xna {
static constexpr Int XnbVersionOffset = 4;
static constexpr Int XnbFileSizeOffset = 6;
static constexpr Int XnbPrologueSize = 10;
inline static const String FilenameExt = ".xnb";
};
//
@ -111,39 +124,105 @@ namespace xna {
template <class T>
void ContentWriter::WriteObject(T& value) {
Exception::ThrowTIsNull(value);
const auto type = typeof<T>();
Int _;
auto typeWriter = GetTypeWriter(*type, _);
InvokeWriter<T>(value, *typeWriter);
}
template <class T>
void ContentWriter::WriteObject(T& value, ContentTypeWriter& writer) {
auto contentTypeWriter = reinterpret_cast<ContentTypeWriter_T<T>*>(&writer);
if (_writer) {
contentTypeWriter->Write(*this, value);
}
else {
Object _value = value;
writer.Write(*this, _value);
}
}
template <class T>
void ContentWriter::WriteRawObject(T& value) {
Exception::ThrowTIsNull(value);
const auto type = typeof<T>();
Int _;
auto typeWriter = GetTypeWriter(*type, _);
InvokeWriter<T>(value, *typeWriter);
}
template <class T>
void ContentWriter::WriteRawObject(T& value, ContentTypeWriter& typeWriter) {
Exception::ThrowTIsNull(value);
InvokeWriter<T>(value, typeWriter);
}
template <class T>
void ContentWriter::WriteSharedResource(T& value) {
if constexpr (XnaHelper::IsSmartPoint<T>()) {
if (value == nullptr)
Write7BitEncodedInt(0);
}
else {
Int num;
Object obj = value;
if (!sharedResourceNames.contains(value)) {
num = sharedResourceNames.size() + 1;
sharedResourceNames.emplace(obj, num);
sharedResources.push(obj);
}
else {
num = sharedResourceNames[value];
}
Write7BitEncodedInt(num);
}
}
template <class T>
void ContentWriter::WriteExternalReference(ExternalReference<T>& reference) {
void ContentWriter::WriteExternalReference(ExternalReference<T>& reference) {
const auto& filename1 = reference.FileName();
if (filename1.empty()) {
Write("");
}
else {
String filename2;
if (filename1.ends_with(FilenameExt))
filename2 = filename1.substr(0, filename.size() - FilenameExt.size());
else
Exception::Throw(Exception::INVALID_OPERATION);
if(!filename2.starts_with(rootDirectory))
Exception::Throw(Exception::INVALID_OPERATION);
Exception::Throw(Exception::NOT_IMPLEMENTED);
}
}
template <class T>
void ContentWriter::InvokeWriter(T& value, ContentTypeWriter& writer) {
auto contentTypeWriter = reinterpret_cast<ContentTypeWriter_T<T>*>(&writer);
if (contentTypeWriter) {
contentTypeWriter->Write(*this, value);
}
else {
Object obj = value;
writer.Write(*this, obj);
}
}
}