2020-09-19 16:08:55 +00:00
|
|
|
#include "ScriptHeadersExporter.hpp"
|
|
|
|
#include <PkmnLib/ScriptResolving/AngelScript/AngelScriptResolver.hpp>
|
|
|
|
#include <filesystem>
|
|
|
|
|
|
|
|
static bool replace(std::string& str, const std::string& from, const std::string& to) {
|
|
|
|
size_t start_pos = str.find(from);
|
|
|
|
if (start_pos == std::string::npos)
|
|
|
|
return false;
|
|
|
|
str.replace(start_pos, from.length(), to);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-10-23 12:12:22 +00:00
|
|
|
static void PrintObjectTypeDef(asITypeInfo* type, const std::filesystem::path& dir) {
|
|
|
|
auto name = std::string(type->GetName());
|
|
|
|
if (name == "string" || name == "array")
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::fstream fs;
|
|
|
|
fs.open((dir / name).concat(".astypedef"), std::fstream::out);
|
|
|
|
|
2021-10-30 09:49:52 +00:00
|
|
|
if ((type->GetFlags() & asOBJ_VALUE) != 0 && (type->GetFlags() & asOBJ_ASHANDLE) == 0) {
|
2021-10-23 12:12:22 +00:00
|
|
|
fs << "valuetype";
|
2021-10-30 09:49:52 +00:00
|
|
|
} else {
|
2021-10-23 12:12:22 +00:00
|
|
|
fs << "type";
|
|
|
|
}
|
|
|
|
|
|
|
|
fs << " " << type->GetName();
|
|
|
|
if ((type->GetFlags() & asOBJ_TEMPLATE) != 0) {
|
|
|
|
fs << "<";
|
|
|
|
for (asUINT i = 0; i < type->GetSubTypeCount(); ++i) {
|
|
|
|
if (i != 0) {
|
|
|
|
fs << ", ";
|
|
|
|
}
|
|
|
|
fs << type->GetSubType(i)->GetName();
|
|
|
|
}
|
|
|
|
fs << ">";
|
|
|
|
}
|
|
|
|
fs << " {" << std::endl;
|
|
|
|
|
|
|
|
auto behaviourCount = type->GetBehaviourCount();
|
|
|
|
for (asUINT j = 0; j < behaviourCount; j++) {
|
|
|
|
if (name == "ref")
|
|
|
|
break;
|
|
|
|
if (name == "dictionaryValue")
|
|
|
|
break;
|
|
|
|
asEBehaviours behaviourType;
|
|
|
|
auto behaviour = type->GetBehaviourByIndex(j, &behaviourType);
|
|
|
|
if (behaviourType > 4) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
auto decl = std::string(behaviour->GetDeclaration(false, false, true));
|
|
|
|
if (behaviourType == asBEHAVE_CONSTRUCT || behaviourType == asBEHAVE_FACTORY) {
|
|
|
|
replace(decl, type->GetName(), "void f");
|
|
|
|
}
|
|
|
|
if (behaviourType == asBEHAVE_DESTRUCT) {
|
|
|
|
replace(decl, std::string("~") + type->GetName(), "void f");
|
|
|
|
}
|
|
|
|
if (behaviourType == asBEHAVE_LIST_CONSTRUCT || behaviourType == asBEHAVE_LIST_FACTORY) {
|
|
|
|
replace(decl, "$list", "f");
|
|
|
|
}
|
|
|
|
fs << " behave " << behaviourType << " " << decl << ";" << std::endl;
|
|
|
|
}
|
|
|
|
auto propertyCount = type->GetMethodCount();
|
|
|
|
for (asUINT j = 0; j < propertyCount; j++) {
|
|
|
|
auto method = type->GetMethodByIndex(j);
|
|
|
|
if (method->IsProperty()) {
|
|
|
|
auto name = std::string(method->GetName());
|
|
|
|
auto decl = std::string(method->GetDeclaration(false, true, false));
|
|
|
|
auto realName = name.substr(4);
|
2021-11-27 10:48:49 +00:00
|
|
|
if (method->GetParamCount() > 0 && !name.starts_with("set_")) {
|
|
|
|
fs << " " << decl << " property;" << std::endl;
|
|
|
|
} else if (name.starts_with("get_")) {
|
|
|
|
replace(decl, name, realName);
|
|
|
|
replace(decl, "() const", " { get const; ");
|
|
|
|
replace(decl, "()", " { get; ");
|
2021-10-23 12:12:22 +00:00
|
|
|
|
2021-11-27 10:48:49 +00:00
|
|
|
fs << " " << decl;
|
|
|
|
auto setMethod = type->GetMethodByName(("set_" + realName).c_str());
|
|
|
|
if (setMethod != nullptr) {
|
|
|
|
auto setDecl = std::string(setMethod->GetDeclaration(false, true, false));
|
|
|
|
if (setDecl.find("const") != std::string::npos) {
|
|
|
|
fs << "set const; ";
|
|
|
|
} else {
|
|
|
|
fs << "set; ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fs << "};" << std::endl;
|
|
|
|
} else if (name.starts_with("set")) {
|
|
|
|
auto getMethod = type->GetMethodByName(("get_" + realName).c_str());
|
|
|
|
if (getMethod != nullptr) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
replace(decl, name, realName);
|
|
|
|
replace(decl, "() const", " { set const; }");
|
|
|
|
replace(decl, "()", " { set; }");
|
|
|
|
fs << "\t" << decl << ";" << std::endl;
|
|
|
|
}
|
2021-10-23 12:12:22 +00:00
|
|
|
} else {
|
|
|
|
auto name = std::string(method->GetName());
|
|
|
|
auto decl = std::string(method->GetDeclaration(false, true, true));
|
|
|
|
replace(decl, "&in", " &in");
|
|
|
|
replace(decl, "&out", " &out");
|
|
|
|
replace(decl, "ref", "ref@");
|
|
|
|
fs << " " << decl << ";" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fs << "}" << std::endl;
|
|
|
|
fs.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void PrintScriptObject(asITypeInfo* type, const std::filesystem::path& dir) {
|
2020-09-19 16:08:55 +00:00
|
|
|
auto name = std::string(type->GetName());
|
|
|
|
if (name == "string" || name == "array" || name == "ref")
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::fstream fs;
|
|
|
|
fs.open((dir / name).concat(".as"), std::fstream::out);
|
|
|
|
|
|
|
|
auto isAbstract = (type->GetFlags() & asEObjTypeFlags::asOBJ_ABSTRACT) != 0;
|
|
|
|
fs << "shared ";
|
|
|
|
if (isAbstract)
|
|
|
|
fs << "abstract class ";
|
|
|
|
else
|
|
|
|
fs << "interface ";
|
|
|
|
fs << type->GetName() << " {" << std::endl;
|
|
|
|
auto propertyCount = type->GetMethodCount();
|
|
|
|
for (asUINT j = 0; j < propertyCount; j++) {
|
|
|
|
auto method = type->GetMethodByIndex(j);
|
|
|
|
if (method->IsProperty()) {
|
|
|
|
auto name = std::string(method->GetName());
|
|
|
|
auto decl = std::string(method->GetDeclaration(false, true, false));
|
|
|
|
auto realName = name.substr(4);
|
2021-11-27 10:48:49 +00:00
|
|
|
if (name.starts_with("get_")) {
|
|
|
|
replace(decl, name, realName);
|
|
|
|
replace(decl, "() const", " get const; ");
|
|
|
|
replace(decl, "()", " get; ");
|
2020-09-19 16:08:55 +00:00
|
|
|
|
2021-11-27 10:48:49 +00:00
|
|
|
fs << "\t"
|
|
|
|
<< "{" << decl;
|
|
|
|
auto setMethod = type->GetMethodByName(("set_" + realName).c_str());
|
|
|
|
if (setMethod != nullptr) {
|
|
|
|
auto setDecl = replace(decl, name, realName);
|
|
|
|
replace(decl, "() const", " set const; ");
|
|
|
|
replace(decl, "()", " set; ");
|
|
|
|
fs << setDecl;
|
|
|
|
}
|
|
|
|
|
|
|
|
fs << "}" << std::endl;
|
|
|
|
} else if (name.starts_with("set")) {
|
|
|
|
auto getMethod = type->GetMethodByName(("get_" + realName).c_str());
|
|
|
|
if (getMethod != nullptr) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
replace(decl, name, realName);
|
|
|
|
replace(decl, "() const", " set const; ");
|
|
|
|
replace(decl, "()", " set; ");
|
|
|
|
fs << "\t"
|
|
|
|
<< "{" << decl << "}" << std::endl;
|
|
|
|
}
|
2020-09-19 16:08:55 +00:00
|
|
|
} else {
|
|
|
|
auto name = std::string(method->GetName());
|
|
|
|
if (name == "opAssign")
|
|
|
|
continue;
|
2021-10-30 09:49:52 +00:00
|
|
|
if (name == "GetOwner") {
|
|
|
|
fs << "\tref@ __owner;" << std::endl << std::endl;
|
|
|
|
}
|
2020-09-19 16:08:55 +00:00
|
|
|
auto decl = std::string(method->GetDeclaration(false, true, true));
|
|
|
|
replace(decl, "&in", " &in");
|
|
|
|
replace(decl, "&out", " &out");
|
2021-10-30 09:49:52 +00:00
|
|
|
replace(decl, "ref", "ref@");
|
2020-09-19 16:08:55 +00:00
|
|
|
fs << "\t" << decl;
|
2021-10-30 09:49:52 +00:00
|
|
|
if (isAbstract) {
|
|
|
|
if (method->GetReturnTypeId() == 0) {
|
2021-10-23 12:12:22 +00:00
|
|
|
fs << "{};" << std::endl;
|
2021-10-30 09:49:52 +00:00
|
|
|
} else {
|
|
|
|
if (name == "GetOwner") {
|
|
|
|
fs << "{ return __owner; };" << std::endl;
|
|
|
|
} else if (method->GetReturnTypeId() == asTYPEID_BOOL) {
|
2021-10-23 12:12:22 +00:00
|
|
|
fs << "{ return false; };" << std::endl;
|
2021-10-30 09:49:52 +00:00
|
|
|
} else {
|
2021-10-23 12:12:22 +00:00
|
|
|
fs << "{ return 0; };" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
2021-10-30 09:49:52 +00:00
|
|
|
} else
|
2020-09-19 16:08:55 +00:00
|
|
|
fs << ";" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fs << "}" << std::endl;
|
|
|
|
fs.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScriptHeadersExporter::Export(const std::string& outPath) {
|
|
|
|
auto resolver = new AngelScriptResolver();
|
|
|
|
resolver->Initialize(nullptr);
|
|
|
|
resolver->FinalizeModule();
|
|
|
|
auto module = resolver->GetMainModule();
|
|
|
|
auto engine = module->GetEngine();
|
|
|
|
auto typesCount = engine->GetObjectTypeCount();
|
|
|
|
std::filesystem::path dir(outPath);
|
|
|
|
for (asUINT i = 0; i < typesCount; i++) {
|
|
|
|
auto type = engine->GetObjectTypeByIndex(i);
|
2021-10-23 12:12:22 +00:00
|
|
|
if ((type->GetTypeId() & asTYPEID_SCRIPTOBJECT) != 0) {
|
|
|
|
PrintScriptObject(type, dir);
|
|
|
|
} else {
|
|
|
|
PrintObjectTypeDef(type, dir);
|
|
|
|
}
|
2020-09-19 16:08:55 +00:00
|
|
|
}
|
|
|
|
auto moduleTypesCount = module->GetObjectTypeCount();
|
|
|
|
for (asUINT i = 0; i < moduleTypesCount; i++) {
|
|
|
|
auto type = module->GetObjectTypeByIndex(i);
|
2021-10-23 12:12:22 +00:00
|
|
|
if ((type->GetTypeId() & asTYPEID_SCRIPTOBJECT) != 0) {
|
|
|
|
PrintScriptObject(type, dir);
|
|
|
|
} else {
|
|
|
|
PrintObjectTypeDef(type, dir);
|
|
|
|
}
|
2020-09-19 16:08:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto enumCount = engine->GetEnumCount();
|
|
|
|
for (asUINT i = 0; i < enumCount; i++) {
|
|
|
|
auto en = engine->GetEnumByIndex(i);
|
|
|
|
auto name = en->GetName();
|
|
|
|
std::fstream fs;
|
2021-10-23 12:12:22 +00:00
|
|
|
fs.open((dir / name).concat(".astypedef"), std::fstream::out);
|
2020-09-19 16:08:55 +00:00
|
|
|
|
2021-10-23 12:12:22 +00:00
|
|
|
fs << "enum " << en->GetName() << " {" << std::endl;
|
2020-09-19 16:08:55 +00:00
|
|
|
auto valueCount = en->GetEnumValueCount();
|
|
|
|
for (asUINT j = 0; j < valueCount; j++) {
|
|
|
|
int val;
|
|
|
|
auto name = en->GetEnumValueByIndex(j, &val);
|
|
|
|
fs << "\t" << name << " = " << val << "," << std::endl;
|
|
|
|
}
|
|
|
|
fs << "}" << std::endl;
|
|
|
|
fs.close();
|
|
|
|
}
|
2021-10-23 12:12:22 +00:00
|
|
|
|
|
|
|
auto globalFuncs = engine->GetGlobalFunctionCount();
|
2021-10-30 09:49:52 +00:00
|
|
|
if (globalFuncs > 0) {
|
2021-10-23 12:12:22 +00:00
|
|
|
std::fstream fs;
|
|
|
|
fs.open((dir / "globals").concat(".astypedef"), std::fstream::out);
|
|
|
|
|
|
|
|
for (asUINT i = 0; i < globalFuncs; ++i) {
|
|
|
|
auto func = engine->GetGlobalFunctionByIndex(i);
|
|
|
|
fs << "func " << func->GetDeclaration(false, false, true) << ";" << std::endl;
|
|
|
|
}
|
|
|
|
}
|
2020-09-19 16:08:55 +00:00
|
|
|
}
|