156 lines
8.1 KiB
JavaScript
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
|