zengine/engine/tools/make_plugin/src/main.cpp

176 lines
5.3 KiB
C++
Raw Normal View History

2024-07-20 18:04:19 +08:00
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
#include <memory_resource>
#include <stack>
#include <optional>
#include <sstream>
2024-07-24 14:42:14 +08:00
#include "archive/json.h"
2024-07-20 18:04:19 +08:00
namespace pmr {
using std::pmr::monotonic_buffer_resource;
using std::pmr::vector;
using std::pmr::string;
}
pmr::monotonic_buffer_resource pool;
const char* MODULE_DEPENDENCY = "MODULE_DEPENDENCY";
const char* IMPLEMENT_DYNAMIC_MODULE = "IMPLEMENT_DYNAMIC_MODULE";
const char* IMPLEMENT_STATIC_MODULE = "IMPLEMENT_STATIC_MODULE";
std::string_view module_macro[] = { MODULE_DEPENDENCY , IMPLEMENT_DYNAMIC_MODULE , IMPLEMENT_STATIC_MODULE };
struct MacroData{
const char* macro{nullptr};
pmr::vector<pmr::string> args;
MacroData() :args(&pool) {}
MacroData(const pmr::vector<pmr::string>& args):args(args) {}
};
pmr::vector<pmr::string> parseArgs(std::string_view& str) {
pmr::vector<pmr::string> args(&pool);
std::stack<char> stack;
enum EParseState {
EEmpty,
EBody,
};
EParseState state = EEmpty;
int n = 0;
char segment[1024];
for (char c : str) {
switch (state)
{
case EEmpty:
{
if (c == ' ' || c == '\t')
break;
state = EBody;
if (c == '(' && stack.empty()) {
stack.push(c);
break;
}
}
case EBody:
{
if (c == '(' || c == '{' || c == '[' || (c == '"' && stack.top() != '"')) {
stack.push(c);
}else{
char t = stack.top();
if ((t == '(' && c == ')') || (t == '[' && c == ']') || (t == '{' && c == '}') || (t == '"' && c == '"')) {
stack.pop();
}
}
if (stack.empty()) {
std::string_view view(segment, n);
args.push_back(pmr::string(view, &pool));
return args;
}
if (c == ',' && stack.size() == 1) {
std::string_view view(segment, n);
args.push_back(pmr::string(view, &pool));
n = 0;
state = EEmpty;
}
else {
segment[n++] = c;
}
break;
}
default:
break;
}
}
return args;
}
std::optional<MacroData> parseLine(std::string_view line) {
for (auto macro : module_macro) {
size_t pos = line.find(macro);
if (pos != std::string_view::npos) {
line = line.substr(pos + macro.size());
MacroData md{ parseArgs(line) };
md.macro = macro.data();
std::cout << line << std::endl;
return md;
}
}
return std::optional<MacroData>{};
}
// 读取文件并返回每一行内容
pmr::vector<MacroData> readFile(const char* file_path) {
pmr::vector<MacroData> lines(&pool);
std::ifstream file(file_path);
if (!file.is_open()) {
//std::cerr << "Failed to open file: " << file_path << std::endl;
return lines;
}
std::string line;
while (std::getline(file, line)) {
std::string_view line_view(line);
if (auto md = parseLine(line_view)) {
lines.push_back(md.value());
}
}
file.close();
return lines;
}
void writeFile(const char* file_path, std::string_view data) {
std::ofstream file(file_path, 0);
file.write(data.data(), data.size());
file.close();
}
void genLua(const char* file_path, const pmr::vector<MacroData>& mdList) {
std::ostringstream oss;
oss << "{\n";
for (auto& md : mdList) {
if (md.macro == MODULE_DEPENDENCY) {
oss << "\t{";
for (auto& args : md.args) {
if (args[0] != '{') {
oss << '"' << args << "\", ";
}
else {
oss << args;
}
}
oss << "},\n";
}
}
oss << '}';
writeFile(file_path, oss.str());
}
2024-07-24 14:42:14 +08:00
namespace api {
struct Guid {
int a;
float b;
};
template<>
struct JsonSerde<Guid> {
inline static bool Read(yyjson_val* node, Any any) {
Guid& v = *any.CastTo<Guid*>();
JsonRead(yyjson_obj_get(node, "a"), v.a);
JsonRead(yyjson_obj_get(node, "b"), v.b);
return true;
}
inline static yyjson_mut_val* Write(yyjson_mut_doc* doc, Any any) {
Guid& v = *any.CastTo<Guid*>();
auto obj = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, obj, "a", JsonWrite(doc, v.a));
yyjson_mut_obj_add_val(doc, obj, "b", JsonWrite(doc, v.b));
return obj;
}
};
}
2024-07-20 18:04:19 +08:00
void genPlugin(const char* file_path, const pmr::vector<MacroData>& mdList) {
2024-07-24 14:42:14 +08:00
api::Guid guid;
guid.a = 1243;
std::string_view data = api::JsonSerialize(guid);
auto res = api::JsonDeserialize<api::Guid>(data);
if (res) {
api::Guid g2 = res.value();
int a = g2.a;
int b = g2.b;
}
2024-07-20 18:04:19 +08:00
}
int main() {
const char* file_path = R"(F:\engine\zengine\engine\modules\render\vulkan\include\vulkan\module.h)";
auto mdList = readFile(file_path);
genLua(R"(F:\engine\zengine\build\.gens\vulkan\windows\xmake.lua)", mdList);
genPlugin(R"(F:\engine\zengine\build\.gens\vulkan\windows\xmake.lua)", mdList);
return 0;
}