Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Extension: Refactor code into separate files (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: Max Oberaigner <[email protected]>
  • Loading branch information
moberer and Max Oberaigner authored Apr 18, 2024
1 parent cb4534c commit 2747602
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 35 deletions.
58 changes: 23 additions & 35 deletions rust/godot-plugin/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
// Main entry point from the Godot side.
//
// Registers an Engine Singleton.
// Provides the Top-Level API to GDScript.

use godot::builtin::Array;
use godot::engine::Engine;
use godot::prelude::*;

use std::sync::{Mutex, OnceLock};

use compiler::Ast;
use compiler::Compilable;
use godot::engine::Engine;

use crate::signals::*;
use crate::state::*;

mod signals;
mod state;

// Register this plugin as a Godot Extension
struct MyExtension {}

fn ast() -> &'static Mutex<Ast> {
static AST: OnceLock<Mutex<Ast>> = OnceLock::new();
AST.get_or_init(|| Mutex::new(Ast::default()))
}

#[gdextension]
unsafe impl ExtensionLibrary for MyExtension {
fn on_level_init(level: InitLevel) {
Expand Down Expand Up @@ -59,6 +63,17 @@ impl Api {
ast.to_godot_ast()
}

#[func]
fn get_all_sprites() -> Array<GString> {
todo!("not implemented")
}

#[func]
fn set_current_sprite(id: i64) {
let mut state = editor_state().lock().unwrap();
state.set_current_sprite(id);
}

#[func]
fn compile() -> GString {
let ast = ast().lock().unwrap();
Expand Down Expand Up @@ -90,30 +105,3 @@ fn to_godot_ast(a: &compiler::ast::Statement) -> i64 {

// -----------------------------------------------------------
//
enum GlobalSignals {
ScriptUpdated,
}

fn global_notify(signal: GlobalSignals) {
let mut global_signals = get_autoload("/root/GlobalSignals");

let signal_name = match signal {
GlobalSignals::ScriptUpdated => "script_updated",
}
.into();

global_signals.emit_signal(signal_name, &[]);
}

fn get_autoload(name: &str) -> Gd<Node> {
let name: NodePath = StringName::from(name).into();

Engine::singleton()
.get_main_loop()
.expect("could not get main loop")
.cast::<SceneTree>()
.get_root()
.expect("could not get root of scene")
.get_node(name)
.expect("could not find element in scene")
}
37 changes: 37 additions & 0 deletions rust/godot-plugin/src/signals.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// This file handles the uncanny mechanics of sending a notification signal
// (as implemented by godot) from this Godot Engine Singleton to
//
// the top-level "GlobalSignals" autoloaded Scene.
// From there the signals can be further dispached in GDScript
// by connecting to this signal.

use godot::engine::Engine;
use godot::prelude::*;

pub enum GlobalSignals {
ScriptUpdated,
}

pub fn global_notify(signal: GlobalSignals) {
let mut global_signals = get_autoload("/root/GlobalSignals");

let signal_name = match signal {
GlobalSignals::ScriptUpdated => "script_updated",
}
.into();

global_signals.emit_signal(signal_name, &[]);
}

fn get_autoload(name: &str) -> Gd<Node> {
let name: NodePath = StringName::from(name).into();

Engine::singleton()
.get_main_loop()
.expect("could not get main loop")
.cast::<SceneTree>()
.get_root()
.expect("could not get root of scene")
.get_node(name)
.expect("could not find element in scene")
}
34 changes: 34 additions & 0 deletions rust/godot-plugin/src/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// "Server-Side" state of the Godot Project.
//
// Keeps a hold of the currently selected project,
// script, etc.
//
// TODO: Rethink wheter this is really the best way to do this,
// or whether we should just send the full selector down with
// every call from the GDScript side.

use std::sync::{Mutex, OnceLock};

use compiler::Ast;

pub fn ast() -> &'static Mutex<Ast> {
static AST: OnceLock<Mutex<Ast>> = OnceLock::new();
AST.get_or_init(|| Mutex::new(Ast::default()))
}

#[derive(Default)]
pub struct EditorState {
current_sprite: Option<i64>,
}

impl EditorState {
pub fn set_current_sprite(&mut self, id: i64) {
// TODO: Validate whether sprite_id is valid!
self.current_sprite = Some(id);
}
}

pub fn editor_state() -> &'static Mutex<EditorState> {
static EDITOR_STATE: OnceLock<Mutex<EditorState>> = OnceLock::new();
EDITOR_STATE.get_or_init(|| Mutex::new(EditorState::default()))
}

0 comments on commit 2747602

Please sign in to comment.