rokojori-godot/rokojori-cpp-generator/builds/CppCreator.js

156 lines
8.1 KiB
JavaScript

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CppCreator = void 0;
const CppClassMember_1 = require("./CppClassMember");
const CppHeaderCreator_1 = require("./CppHeaderCreator");
const CppImplementationCreator_1 = require("./CppImplementationCreator");
const Files_1 = require("./library/Files");
const Texts_1 = require("./library/Texts");
class CppCreator {
static createTypeRegistration(className) {
return `ClassDB::register_class<${className}>();`;
}
static createIncludes(className) {
console.log("Create include", className);
let godotClasses = {
"Node": "scene/main/node.h",
"Node2D": "scene/2d/node_2d.h",
"Node3D": "scene/3d/node_3d.h",
"Resource": "core/io/resource.h"
};
if (godotClasses[className]) {
return `#include "${godotClasses[className]}"`;
}
return `#include "./${className}.h"`;
}
static grabMembers(membersData, accessModifier) {
let members = [];
if (!membersData) {
return members;
}
for (let it in membersData) {
if (!membersData.hasOwnProperty(it)) {
continue;
}
let nameDefinition = it;
let memberData = membersData[it];
let actionRegex = /^\s*action\s+(\w+)\s*$/;
if (actionRegex.test(nameDefinition)) {
let name = actionRegex.exec(nameDefinition)[1];
let upperCaseName = name[0].toUpperCase() + name.substring(1);
let actionName = `on${upperCaseName}`;
let signal = `signal ${name}()`;
let actionGetter = `virtual get_${actionName}():Ref<RJAction>`;
let actionSetter = `virtual set_${actionName}()`;
members.push(new CppClassMember_1.CppClassMember(accessModifier, signal, {}));
members.push(new CppClassMember_1.CppClassMember("protected", "m_" + name, {}));
members.push(new CppClassMember_1.CppClassMember(accessModifier, actionGetter, {}));
members.push(new CppClassMember_1.CppClassMember(accessModifier, actionSetter, { "action": "Ref<RJAction>" }));
}
else {
let classMember = new CppClassMember_1.CppClassMember(accessModifier, nameDefinition, memberData);
members.push(classMember);
}
}
return members;
}
static getHeaderDefine(className) {
className = className.replace(/^RJ/, "");
let output = [className[0]];
for (let i = 1; i < className.length; i++) {
let character = className[i];
let upperCaseCharacter = character.toUpperCase();
if (character === upperCaseCharacter) {
output.push("_");
}
output.push(upperCaseCharacter);
}
className = output.join("");
return "ROKOJORI__" + className + "_H";
}
static getRegistratedTypes(text) {
let matches = Texts_1.Texts.getMatches(text, CppCreator.classRegistrationRegex);
let types = matches.map(m => {
return { match: m.match, index: m.index, type: CppCreator.classRegistrationRegex.exec(m.match)[1] };
});
return types;
}
static createCppFiles(definitionPath, types, missingTypes) {
return __awaiter(this, void 0, void 0, function* () {
console.log("Creating: ", definitionPath);
let jsonPath = definitionPath;
// path.join( definitionsPath, definitionPath );
let isDir = yield Files_1.Files.isDirectory(jsonPath);
if (isDir) {
let files = yield Files_1.Files.getFiles(jsonPath);
for (let file of files) {
yield CppCreator.createCppFiles(Texts_1.Texts.joinPaths(jsonPath, file), types, missingTypes);
}
return Promise.resolve();
}
let data = yield Files_1.Files.loadJSON(jsonPath);
//console.log( "data:", jsonPath, data );
let classNameResult = /(\w+)(?:\:(\w+))?/.exec(data.class);
let className = classNameResult[1];
let extendingClass = classNameResult[2];
let headerDefine = CppCreator.getHeaderDefine(className);
let fromProtectedMembers = CppCreator.grabMembers(data.protected, "protected");
let fromPublicMembers = CppCreator.grabMembers(data.public, "public");
let protectedMembers = [];
let publicMembers = [];
let insertMember = (m) => {
let container = m.accessModifier === "public" ? publicMembers : protectedMembers;
container.push(m);
};
fromProtectedMembers.forEach(m => insertMember(m));
fromPublicMembers.forEach(m => insertMember(m));
let allMembers = [].concat(protectedMembers).concat(publicMembers);
let protectedHeader = protectedMembers.map(m => m.getHeaderDefinition()).join("\n ");
let publicHeader = publicMembers.map(m => m.getHeaderDefinition()).join("\n ");
let properties = publicMembers.filter(m => !m.isMethod);
let propertyDefinitions = properties.map(p => p.getPropertyHeaderDefinition()).join("\n ");
protectedHeader += "\n\n " + propertyDefinitions;
let methodBindings = allMembers.map(m => m.getMethodBinding(className)).join("\n ");
let initializers = allMembers.filter(m => m.isMemberWithInitialValue).map(m => m.getMemberInitializer()).join("\n ");
let includes = "";
if (data.includes) {
let mappedIncludes = data.includes.map((inc) => `#include "${inc}"`);
includes = mappedIncludes.join("\n");
}
let extendingClassInclude = CppCreator.createIncludes(extendingClass);
includes += "\n" + extendingClassInclude;
let header = CppHeaderCreator_1.CppHeaderCreator.create(className, extendingClass, headerDefine, protectedHeader, publicHeader, includes);
let constructorExpressions = initializers;
let destructorExpressions = "";
let methodImplementations = "";
let propertyImplementations = properties.map(p => p.getPropertyImplementation(className)).join("\n");
methodImplementations += propertyImplementations;
let implementation = CppImplementationCreator_1.CppImplementationCreator.craete(className, methodBindings, constructorExpressions, destructorExpressions, methodImplementations);
//console.log( header );
//console.log( implementation );
let hasType = types.find(t => t.type === className);
if (!hasType) {
missingTypes.push(className);
}
let rawFilePath = Texts_1.Texts.joinPaths(CppCreator.outputPath, className);
yield Files_1.Files.saveUTF8(rawFilePath + ".h", header);
yield Files_1.Files.saveUTF8(rawFilePath + ".cpp", implementation);
return Promise.resolve();
});
}
}
exports.CppCreator = CppCreator;
CppCreator.definitionsPath = __dirname + "/../../rokojori-action-library-definitions";
CppCreator.outputPath = __dirname + "/../../rokojori-action-library";
CppCreator.registerTypesPath = CppCreator.outputPath + "/register_types.cpp";
CppCreator.classRegistrationRegex = /ClassDB\:\:register_class\<(\w+)\>\(\)\;/;
//# sourceMappingURL=CppCreator.js.map