mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
removed exit node, nex function widget
This commit is contained in:
parent
3e00fb1c83
commit
6d544f5879
13 changed files with 285 additions and 100 deletions
|
|
@ -17,6 +17,11 @@ public:
|
|||
PROJECT_TYPE_PRIMITIVE = 2
|
||||
};
|
||||
|
||||
struct FunctionInfo {
|
||||
std::string uuid;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
virtual ~IStoryProject() {};
|
||||
|
||||
virtual std::string GetName() const = 0;
|
||||
|
|
@ -26,6 +31,7 @@ public:
|
|||
virtual std::string GetUuid() const = 0;
|
||||
virtual std::string GetTitleImage() const = 0;
|
||||
virtual std::string GetTitleSound() const = 0;
|
||||
virtual std::vector<FunctionInfo> GetFunctionsList() const = 0;
|
||||
|
||||
virtual void SetTitleImage(const std::string &titleImage) = 0;
|
||||
virtual void SetTitleSound(const std::string &titleSound) = 0;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
#include "ast_builder.h"
|
||||
#include "assembly_generator.h"
|
||||
#include "call_function_node.h"
|
||||
|
||||
class AssemblyGeneratorChip32 : public AssemblyGenerator
|
||||
{
|
||||
public:
|
||||
AssemblyGeneratorChip32(const GeneratorContext& context)
|
||||
: AssemblyGenerator(context)
|
||||
, m_currentContext(FunctionContext::MAIN_PROGRAM)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -28,6 +30,13 @@ public:
|
|||
GenerateOperatorNode(node);
|
||||
}
|
||||
else if (node->IsType<FunctionEntryNode>()) {
|
||||
// Détecter si c'est le main ou une sous-fonction
|
||||
// Weight 100 = fonction principale (main)
|
||||
auto* entry = node->GetAs<FunctionEntryNode>();
|
||||
m_currentContext = (entry->GetWeight() >= 100)
|
||||
? FunctionContext::MAIN_PROGRAM
|
||||
: FunctionContext::SUB_FUNCTION;
|
||||
|
||||
GenerateFunctionEntry(node);
|
||||
}
|
||||
else if (node->IsType<BranchNode>()) {
|
||||
|
|
@ -36,12 +45,20 @@ public:
|
|||
else if (node->IsType<PrintNode>()) {
|
||||
GeneratePrintNode(node);
|
||||
}
|
||||
else if (node->IsType<CallFunctionNode>()) {
|
||||
GenerateCallFunctionNode(node);
|
||||
}
|
||||
|
||||
// // If there is no any children, put an halt
|
||||
// Détection automatique des fins de fonction/programme
|
||||
if (node->GetChildCount() == 0)
|
||||
{
|
||||
AddComment("Program exit");
|
||||
m_assembly << " halt\n";
|
||||
if (m_currentContext == FunctionContext::MAIN_PROGRAM) {
|
||||
AddComment("Program exit (automatic)");
|
||||
m_assembly << " halt\n";
|
||||
} else {
|
||||
AddComment("Function return (automatic)");
|
||||
m_assembly << " ret\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +72,12 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
enum class FunctionContext {
|
||||
MAIN_PROGRAM,
|
||||
SUB_FUNCTION
|
||||
};
|
||||
|
||||
FunctionContext m_currentContext;
|
||||
|
||||
virtual void GenerateMain() override {
|
||||
// Program entry point
|
||||
|
|
@ -62,7 +85,39 @@ private:
|
|||
}
|
||||
|
||||
void GenerateFunctionEntry(std::shared_ptr<ASTNode> node) {
|
||||
AddComment("Function Entry");
|
||||
auto* entry = node->GetAs<FunctionEntryNode>();
|
||||
|
||||
if (m_currentContext == FunctionContext::MAIN_PROGRAM) {
|
||||
AddComment("Main function entry");
|
||||
} else {
|
||||
AddComment("Function entry");
|
||||
// Si nécessaire, sauvegarder les registres
|
||||
// m_assembly << " push r0\n";
|
||||
// m_assembly << " push r1\n";
|
||||
// etc.
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateCallFunctionNode(std::shared_ptr<ASTNode> node) {
|
||||
auto* callNode = node->GetAs<CallFunctionNode>();
|
||||
if (!callNode) return;
|
||||
|
||||
std::string functionName = callNode->GetFunctionName();
|
||||
|
||||
AddComment("Call function: " + functionName);
|
||||
m_depth++;
|
||||
|
||||
// Préparer les arguments si nécessaire
|
||||
// Dans votre système, les variables globales sont utilisées
|
||||
// donc pas besoin de passer des arguments sur la pile
|
||||
|
||||
// Appel de la fonction
|
||||
m_assembly << " call " << GetFunctionLabel(functionName) << "\n";
|
||||
|
||||
// Après le retour de la fonction, les variables globales
|
||||
// ont potentiellement été modifiées et sont directement accessibles
|
||||
|
||||
m_depth--;
|
||||
}
|
||||
|
||||
void GenerateBranchNode(std::shared_ptr<ASTNode> node)
|
||||
|
|
@ -88,24 +143,20 @@ private:
|
|||
|
||||
std::string label = printNode->GetLabel();
|
||||
|
||||
|
||||
m_assembly << " push r0\n"
|
||||
<< " push r1\n"
|
||||
<< " lcons r0, $" << label << "\n"
|
||||
<< " lcons r1, 0 ; number of arguments\n" // FIXME: handle arguments
|
||||
<< " syscall 4\n"
|
||||
<< " pop r1\n"
|
||||
<< " pop r0\n";
|
||||
|
||||
// << ""mov r2, %2 // arguments are in r2, r3, r4 etc.
|
||||
|
||||
m_assembly << " push r0\n"
|
||||
<< " push r1\n"
|
||||
<< " lcons r0, $" << label << "\n"
|
||||
<< " lcons r1, 0 ; number of arguments\n" // FIXME: handle arguments
|
||||
<< " syscall 4\n"
|
||||
<< " pop r1\n"
|
||||
<< " pop r0\n";
|
||||
}
|
||||
|
||||
void GenerateOperatorNode(std::shared_ptr<ASTNode> node) {
|
||||
auto* opNode = node->GetAs<OperatorNode>();
|
||||
if (!opNode) return;
|
||||
|
||||
AddComment("Operator: " + std::to_string(static_cast<int>(opNode->GetOperationType())));
|
||||
AddComment("Operator: " + opNode->GetOperatorSymbol());
|
||||
m_depth++;
|
||||
|
||||
// Generate code for variables usage
|
||||
|
|
@ -125,7 +176,7 @@ private:
|
|||
{
|
||||
// Generate code to load the variable value
|
||||
// FIXME: hardcoded 4 bytes, replace by actual real variable size
|
||||
m_assembly << " load r" << reg << ", $" << var->GetLabel() << ", 4" << "; Load variable " << var->GetVariableName() << "\n";
|
||||
m_assembly << " load r" << reg << ", $" << var->GetLabel() << ", 4" << " ; Load variable " << var->GetVariableName() << "\n";
|
||||
m_assembly << " push r" << reg << "\n";
|
||||
}
|
||||
else
|
||||
|
|
@ -135,13 +186,9 @@ private:
|
|||
}
|
||||
reg++;
|
||||
}
|
||||
|
||||
|
||||
// m_assembly << " load r0, " << inputNode.node->GetId() << "\n";
|
||||
}
|
||||
|
||||
|
||||
// Generate operator code
|
||||
// Generate operator code based on type
|
||||
switch (opNode->GetOperationType()) {
|
||||
case OperatorNode::OperationType::ADD:
|
||||
m_assembly << " pop r0\n"
|
||||
|
|
@ -167,28 +214,133 @@ private:
|
|||
<< " div r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::MODULO:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " mod r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::EQUAL:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " cmp r0, r1\n"
|
||||
<< " lcons r0, 1\n"
|
||||
<< " skipz\n"
|
||||
<< " lcons r0, 0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::NOT_EQUAL:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " cmp r0, r1\n"
|
||||
<< " lcons r0, 0\n"
|
||||
<< " skipz\n"
|
||||
<< " lcons r0, 1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::GREATER_THAN:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " cmp r0, r1\n"
|
||||
<< " lcons r0, 1\n"
|
||||
<< " skipgt\n"
|
||||
<< " lcons r0, 0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::LESS_THAN:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " cmp r0, r1\n"
|
||||
<< " lcons r0, 1\n"
|
||||
<< " skiplt\n"
|
||||
<< " lcons r0, 0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::GREATER_EQUAL:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " cmp r0, r1\n"
|
||||
<< " lcons r0, 1\n"
|
||||
<< " skipge\n"
|
||||
<< " lcons r0, 0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::LESS_EQUAL:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " cmp r0, r1\n"
|
||||
<< " lcons r0, 1\n"
|
||||
<< " skiple\n"
|
||||
<< " lcons r0, 0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::AND:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " and r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::GREATER_THAN:
|
||||
case OperatorNode::OperationType::OR:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " gt r0, r0, r1\n"
|
||||
<< " or r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::NOT:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " not r0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::BITWISE_AND:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " and r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::BITWISE_OR:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " or r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::BITWISE_XOR:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " xor r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::BITWISE_NOT:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " not r0\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::LEFT_SHIFT:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " shl r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
case OperatorNode::OperationType::RIGHT_SHIFT:
|
||||
m_assembly << " pop r0\n"
|
||||
<< " pop r1\n"
|
||||
<< " shr r0, r1\n"
|
||||
<< " push r0\n";
|
||||
break;
|
||||
default:
|
||||
// Make voluntary bad assembly
|
||||
m_assembly << "------>>>> OPERATOR NOT IMPLEMENTED: " << opNode->GetOperatorSymbol() << "\n";
|
||||
break;
|
||||
throw std::runtime_error("Unsupported operator type");
|
||||
}
|
||||
|
||||
m_depth--;
|
||||
}
|
||||
|
||||
virtual void Visit(const std::shared_ptr<Variable> v) override
|
||||
// Helper pour générer le label d'une fonction à partir de son nom
|
||||
std::string GetFunctionLabel(const std::string& functionName) {
|
||||
// Convertir le nom de fonction en label valide
|
||||
// Par exemple: "MyFunction" -> ".func_MyFunction"
|
||||
return ".func_" + functionName;
|
||||
}
|
||||
|
||||
virtual void Visit(const std::shared_ptr<Variable> v) override
|
||||
{
|
||||
if (v->IsConstant())
|
||||
{
|
||||
|
|
@ -232,7 +384,4 @@ private:
|
|||
m_assembly << "$" << v->GetLabel() << " DVB, " << (v->GetValue<bool>() ? "1" : "0") << " ; " << v->GetVariableName() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
|
@ -102,6 +102,22 @@ public:
|
|||
return m_weight;
|
||||
}
|
||||
|
||||
void SetupExecutionPorts(bool hasInput = true,
|
||||
int numOutputs = 1,
|
||||
bool customRendering = true)
|
||||
{
|
||||
if (m_behavior != BEHAVIOR_EXECUTION) return;
|
||||
|
||||
if (hasInput) {
|
||||
AddInputPort(Port::Type::EXECUTION_PORT, ">", customRendering);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numOutputs; ++i) {
|
||||
std::string label = (numOutputs == 1) ? ">" : std::to_string(i);
|
||||
AddOutputPort(Port::Type::EXECUTION_PORT, label, customRendering);
|
||||
}
|
||||
}
|
||||
|
||||
void SetId(const std::string &id) { m_uuid = id; }
|
||||
std::string GetId() const { return m_uuid; }
|
||||
|
||||
|
|
@ -121,8 +137,8 @@ public:
|
|||
}
|
||||
|
||||
// Port management
|
||||
void AddInputPort(Port::Type type, const std::string& label) {
|
||||
m_inputPorts.push_back({type, label});
|
||||
void AddInputPort(Port::Type type, const std::string& label, bool customRendering = false) {
|
||||
m_inputPorts.push_back({type, label, customRendering});
|
||||
}
|
||||
|
||||
void AddOutputPort(Port::Type type, const std::string& label, bool customRendering = false) {
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
#include "call_function_node.h"
|
||||
#include "story_project.h"
|
||||
#include "connection.h"
|
||||
#include "sys_lib.h"
|
||||
|
||||
|
||||
CallFunctionNode::CallFunctionNode(const std::string &type)
|
||||
: BaseNode(type, "Call Function Node")
|
||||
{
|
||||
nlohmann::json j{ {"function", ""} };
|
||||
SetInternalData(j);
|
||||
}
|
||||
|
||||
void CallFunctionNode::Initialize()
|
||||
{
|
||||
nlohmann::json j = GetInternalData();
|
||||
// m_image = j["image"].get<std::string>();
|
||||
// m_sound = j["sound"].get<std::string>();
|
||||
}
|
||||
|
||||
|
|
@ -1,19 +1,51 @@
|
|||
// call_function_node.h
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i_story_manager.h"
|
||||
#include "base_node.h"
|
||||
#include "i_script_node.h"
|
||||
#include "i_story_project.h"
|
||||
|
||||
class CallFunctionNode : public BaseNode
|
||||
{
|
||||
public:
|
||||
CallFunctionNode(const std::string &type);
|
||||
CallFunctionNode(const std::string &type)
|
||||
: BaseNode(type, "Call Function Node")
|
||||
, m_functionName("")
|
||||
, m_functionUuid("")
|
||||
{
|
||||
SetBehavior(BaseNode::BEHAVIOR_EXECUTION);
|
||||
SetupExecutionPorts(true, 1, true); // 1 entrée, 1 sortie
|
||||
}
|
||||
|
||||
virtual void Initialize() override;
|
||||
void Initialize() override {
|
||||
// Charger le nom et l'UUID de la fonction depuis les données internes
|
||||
nlohmann::json j = GetInternalData();
|
||||
if (j.contains("functionName")) {
|
||||
m_functionName = j["functionName"].get<std::string>();
|
||||
}
|
||||
if (j.contains("functionUuid")) {
|
||||
m_functionUuid = j["functionUuid"].get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetFunctionName() const {
|
||||
return m_functionName;
|
||||
}
|
||||
|
||||
std::string GetFunctionUuid() const {
|
||||
return m_functionUuid;
|
||||
}
|
||||
|
||||
void SetFunction(const std::string& uuid, const std::string& name) {
|
||||
m_functionUuid = uuid;
|
||||
m_functionName = name;
|
||||
|
||||
// Sauvegarder dans les données internes pour la persistance
|
||||
nlohmann::json j;
|
||||
j["functionName"] = m_functionName;
|
||||
j["functionUuid"] = m_functionUuid;
|
||||
SetInternalData(j);
|
||||
}
|
||||
|
||||
private:
|
||||
nlohmann::json m_content;
|
||||
};
|
||||
|
||||
std::string m_functionName;
|
||||
std::string m_functionUuid;
|
||||
};
|
||||
|
|
@ -11,7 +11,7 @@ public:
|
|||
{
|
||||
SetWeight(100);
|
||||
SetBehavior(BaseNode::BEHAVIOR_EXECUTION);
|
||||
AddOutputPort(BaseNode::Port::Type::EXECUTION_PORT, ">", true);
|
||||
SetupExecutionPorts(false, 1, true);
|
||||
}
|
||||
|
||||
void Initialize() override {
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "base_node.h"
|
||||
|
||||
class FunctionExitNode : public BaseNode
|
||||
{
|
||||
public:
|
||||
FunctionExitNode(const std::string &type)
|
||||
: BaseNode(type, "Function Exit Node")
|
||||
{
|
||||
|
||||
SetBehavior(BaseNode::BEHAVIOR_EXECUTION);
|
||||
}
|
||||
|
||||
void Initialize() override {
|
||||
// Initialisation spécifique pour FunctionExitNode
|
||||
// Par exemple, préparer les sorties nécessaires pour la fonction
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Ajoutez des méthodes spécifiques pour gérer la sortie de la fonction
|
||||
void FinalizeFunctionExit() {
|
||||
// Logique pour finaliser la sortie de la fonction
|
||||
}
|
||||
};
|
||||
|
|
@ -14,18 +14,13 @@ PrintNode::PrintNode(const std::string &type)
|
|||
m_variables[m_label] = v;
|
||||
|
||||
SetBehavior(BaseNode::BEHAVIOR_EXECUTION);
|
||||
|
||||
// Add execution input port (sync)
|
||||
AddInputPort(Port::EXECUTION_PORT, ">");
|
||||
SetupExecutionPorts(true, 1, true);
|
||||
|
||||
// Add 4 data input ports for arguments
|
||||
for (int i = 0; i < MAX_INPUT_COUNT; ++i) {
|
||||
AddInputPort(Port::DATA_PORT, "arg" + std::to_string(i));
|
||||
}
|
||||
|
||||
// Add execution output port
|
||||
AddOutputPort(Port::EXECUTION_PORT, ">");
|
||||
|
||||
|
||||
SetText("");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "story_project.h"
|
||||
#include "story_primitive.h"
|
||||
#include "function_entry_node.h"
|
||||
#include "function_exit_node.h"
|
||||
|
||||
|
||||
static const std::string OperatorNodeUuid = "0226fdac-8f7a-47d7-8584-b23aceb712ec";
|
||||
static const std::string CallFunctionNodeUuid = "02745f38-9b11-49fe-94b1-b2a6b78249fb";
|
||||
|
|
@ -24,7 +24,7 @@ static const std::string VariableNodeUuid = "020cca4e-9cdc-47e7-a6a5-53e4c9152ed
|
|||
static const std::string PrintNodeUuid = "02ee27bc-ff1d-4f94-b700-eab55052ad1c";
|
||||
static const std::string SyscallNodeUuid = "02225cff-4975-400e-8130-41524d8af773";
|
||||
static const std::string FunctionEntryNodeUuid = "02fd145a-b3a6-43c2-83ce-6a187e6d4b5b";
|
||||
static const std::string FunctionExitNodeUuid = "027b723d-2327-4646-a17a-79ddc2e016e4";
|
||||
static const std::string DUMMY_a_prendre_Uuid = "027b723d-2327-4646-a17a-79ddc2e016e4";
|
||||
|
||||
typedef std::shared_ptr<BaseNode> (*GenericCreator)(const std::string &type);
|
||||
|
||||
|
|
@ -44,7 +44,6 @@ public:
|
|||
registerNode<PrintNode>(PrintNodeUuid, std::make_shared<StoryPrimitive>("Print"));
|
||||
registerNode<SyscallNode>(SyscallNodeUuid, std::make_shared<StoryPrimitive>("System call"));
|
||||
registerNode<FunctionEntryNode>(FunctionEntryNodeUuid, std::make_shared<StoryPrimitive>("Function entry"));
|
||||
registerNode<FunctionExitNode>(FunctionExitNodeUuid, std::make_shared<StoryPrimitive>("Function exit"));
|
||||
}
|
||||
|
||||
~NodesFactory() = default;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class StoryPage : public IStoryPage
|
|||
public:
|
||||
StoryPage(const std::string_view uuid)
|
||||
: m_uuid(uuid)
|
||||
, m_name("Unnamed Page")
|
||||
{
|
||||
}
|
||||
~StoryPage() {
|
||||
|
|
@ -26,6 +27,9 @@ public:
|
|||
|
||||
std::string_view Uuid() const { return m_uuid; }
|
||||
|
||||
std::string_view GetName() const { return m_name; }
|
||||
void SetName(const std::string& name) { m_name = name; }
|
||||
|
||||
void AddNode(std::shared_ptr<BaseNode> node) {
|
||||
m_nodes.push_back(node);
|
||||
}
|
||||
|
|
@ -125,6 +129,7 @@ public:
|
|||
{
|
||||
nlohmann::json model;
|
||||
model["uuid"] = m_uuid;
|
||||
model["name"] = m_name;
|
||||
|
||||
nlohmann::json nodes = nlohmann::json::array();
|
||||
for (const auto & n : m_nodes)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ public:
|
|||
return m_uuid;
|
||||
}
|
||||
|
||||
virtual std::vector<FunctionInfo> GetFunctionsList() const override {
|
||||
return std::vector<FunctionInfo>();
|
||||
}
|
||||
|
||||
|
||||
virtual std::string GetTitleImage() const {
|
||||
|
|
|
|||
|
|
@ -268,6 +268,7 @@ bool StoryProject::ModelFromJson(const nlohmann::json &model, NodesFactory &fact
|
|||
// 1. Create the page in memory
|
||||
auto p = std::make_shared<StoryPage>(pageModel["uuid"].get<std::string>());
|
||||
m_pages.push_back(p);
|
||||
p->SetName(pageModel.value("name", "Unnamed Page"));
|
||||
|
||||
// 2. Load the nodes
|
||||
nlohmann::json nodesJsonArray = pageModel["nodes"];
|
||||
|
|
@ -332,6 +333,30 @@ bool StoryProject::CopyProgramTo(uint8_t *memory, uint32_t size)
|
|||
return success;
|
||||
}
|
||||
|
||||
std::vector<IStoryProject::FunctionInfo> StoryProject::GetFunctionsList() const
|
||||
{
|
||||
std::vector<IStoryProject::FunctionInfo> functions;
|
||||
|
||||
// Parcourir toutes les pages du projet
|
||||
for (const auto& page : m_pages)
|
||||
{
|
||||
// Exclure la page main (MainUuid)
|
||||
if (page->Uuid() == MainUuid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ajouter la page à la liste des fonctions disponibles
|
||||
IStoryProject::FunctionInfo info;
|
||||
info.uuid = page->Uuid();
|
||||
info.name = page->GetName();
|
||||
|
||||
functions.push_back(info);
|
||||
}
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
bool StoryProject::GetAssemblyLine(uint32_t pointer_counter, uint32_t &line)
|
||||
{
|
||||
bool success = false;
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public:
|
|||
virtual void SetName(const std::string &name) override { m_name = name; }
|
||||
virtual void SetUuid(const std::string &uuid) override { m_uuid = uuid; }
|
||||
virtual Type GetProjectType() const override { return m_projectType; }
|
||||
std::vector<FunctionInfo> GetFunctionsList() const override;
|
||||
|
||||
// Node interaction
|
||||
std::shared_ptr<StoryPage> CreatePage(const std::string_view uuid);
|
||||
|
|
|
|||
Loading…
Reference in a new issue