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" "platform-dx/audioengine.cpp"
"graphics/gresource.cpp" "graphics/gresource.cpp"
"platform-dx/effect.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) if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET Xn65 PROPERTY CXX_STANDARD 20) 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/writer.hpp"
#include "xna/pipeline/compiler.hpp"
namespace xna { namespace xna {
ContentWriter::ContentWriter( ContentWriter::ContentWriter(
@ -22,6 +23,34 @@ namespace xna {
OutStream = reinterpret_pointer_cast<Stream>(contentData); 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() { void ContentWriter::WriteSharedResources() {
while (sharedResources.size() > 0) { while (sharedResources.size() > 0) {
sharedResources.pop(); sharedResources.pop();

View File

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

View File

@ -20,6 +20,10 @@
#include "helpers.hpp" #include "helpers.hpp"
namespace xna { namespace xna {
//
// Util types
//
using HashValue = size_t;
// //
//C# nameof //C# nameof
@ -221,6 +225,7 @@ namespace xna {
using P_Stream = sptr<Stream>; using P_Stream = sptr<Stream>;
using P_MemoryStream = sptr<MemoryStream>; using P_MemoryStream = sptr<MemoryStream>;
using P_FileStream = sptr<FileStream>; using P_FileStream = sptr<FileStream>;
using P_Type = sptr<Type>;
//Pipeline //Pipeline
using P_ContentWriter = sptr<ContentWriter>; using P_ContentWriter = sptr<ContentWriter>;
using P_ContentCompiler = sptr<ContentCompiler>; 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()); 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_CREATE = "Failed to create component.";
inline static const std::string FAILED_TO_APPLY = "Failed to apply 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."; 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 OUT_OF_BOUNDS = "Out of bounds.";
inline static const std::string END_OF_FILE = "End of file."; 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 #endif

View File

@ -62,6 +62,15 @@ namespace xna {
else else
Exception::Throw(Exception::UNABLE_TO_BUILD_OBJECT, location); 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 { namespace xna {
class ContentCompiler { 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 "pipeline-enums.hpp"
#include "../common/numerics.hpp" #include "../common/numerics.hpp"
#include "../common/color.hpp" #include "../common/color.hpp"
#include "../csharp/type.hpp"
namespace xna { namespace xna {
class ContentTypeWriter { class ContentTypeWriter {
public: public:
virtual String GetRuntimeReader(TargetPlatform targetPlatform) = 0; virtual String GetRuntimeReader(TargetPlatform targetPlatform) = 0;
virtual Int TypeVersion() const { return 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> template <class T>
class ExternalReference { 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. //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: private:
template <class T> void InvokeWriter(T& value, ContentTypeWriter& writer); 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 WriteSharedResources();
void WriteHeader(); void WriteHeader();
void WriteFinalOutput(); void WriteFinalOutput();
@ -94,6 +105,7 @@ namespace xna {
std::vector<P_ContentTypeWriter> typeWriters; std::vector<P_ContentTypeWriter> typeWriters;
std::map<std::any, Int> sharedResourceNames; std::map<std::any, Int> sharedResourceNames;
std::queue<std::any> sharedResources; std::queue<std::any> sharedResources;
std::map<HashValue, Int> typeTable;
private: private:
static constexpr Ushort XnbVersion = 5; static constexpr Ushort XnbVersion = 5;
@ -103,6 +115,7 @@ namespace xna {
static constexpr Int XnbVersionOffset = 4; static constexpr Int XnbVersionOffset = 4;
static constexpr Int XnbFileSizeOffset = 6; static constexpr Int XnbFileSizeOffset = 6;
static constexpr Int XnbPrologueSize = 10; static constexpr Int XnbPrologueSize = 10;
inline static const String FilenameExt = ".xnb";
}; };
// //
@ -111,39 +124,105 @@ namespace xna {
template <class T> template <class T>
void ContentWriter::WriteObject(T& value) { 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> template <class T>
void ContentWriter::WriteObject(T& value, ContentTypeWriter& writer) { 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> template <class T>
void ContentWriter::WriteRawObject(T& value) { 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> template <class T>
void ContentWriter::WriteRawObject(T& value, ContentTypeWriter& typeWriter) { void ContentWriter::WriteRawObject(T& value, ContentTypeWriter& typeWriter) {
Exception::ThrowTIsNull(value);
InvokeWriter<T>(value, typeWriter);
} }
template <class T> template <class T>
void ContentWriter::WriteSharedResource(T& value) { 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> 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> template <class T>
void ContentWriter::InvokeWriter(T& value, ContentTypeWriter& writer) { 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);
}
} }
} }