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:
parent
61aa08ff61
commit
db3258c777
@ -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)
|
||||
|
5
framework/pipeline/compiler.cpp
Normal file
5
framework/pipeline/compiler.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "xna/pipeline/compiler.hpp"
|
||||
|
||||
namespace xna {
|
||||
|
||||
}
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
|
||||
namespace xna {
|
||||
class ContentCompiler {
|
||||
|
||||
public:
|
||||
P_ContentTypeWriter GetTypeWriter(Type const& type, std::vector<P_Type> dependencies);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user