"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`; 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" })); } 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