Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Editor and Export plugin #39

Merged
merged 2 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Godot 4+ specific ignores
.godot/
**/bin/**
!**/bin/.gdignore

# Temporary directories
node_modules/
Expand Down
Empty file added godot/default/bin/.gdignore
Empty file.
65 changes: 65 additions & 0 deletions godot/default/export_presets.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
[preset.0]

name="Windows Desktop"
platform="Windows Desktop"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="bin/fluent-translation.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=2

[preset.0.options]

custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
fluent/strip_comments=true
3 changes: 3 additions & 0 deletions godot/default/test.en.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# this is a comment
## another comment
-term = email
### third kind of comment
HELLO =
{ $unreadEmails ->
[one] You have one unread { -term }.
Expand Down
2 changes: 1 addition & 1 deletion rust/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[env]
GODOT4_BIN = { value = "../build/godot.windows.editor.x86_64.console.exe", relative = true }
GODOT4_BIN = { value = "../build/godot.windows.editor.x86_64.exe", relative = true }
44 changes: 30 additions & 14 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ crate-type = ["cdylib"] # Compile this crate to a dynamic C library.
constcat = "0.5.0"
fluent = { git = "https://github.com/projectfluent/fluent-rs", branch = "main" }
fluent-syntax = { git = "https://github.com/projectfluent/fluent-rs", branch = "main" }
godot = { git = "https://github.com/godot-rust/gdext", branch = "master", features = ["experimental-threads"] }
godot = { git = "https://github.com/godot-rust/gdext", branch = "master", features = ["register-docs", "experimental-threads"] }
itertools = "0.13.0"
unic-langid = "0.9.4"
25 changes: 25 additions & 0 deletions rust/src/fluent/editor_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use godot::{classes::{EditorPlugin, IEditorPlugin}, prelude::*};

use super::FluentExportPlugin;

#[derive(GodotClass)]
#[class(tool, editor_plugin, init, base=EditorPlugin)]
pub struct FluentEditorPlugin {
export_plugin: Option<Gd<FluentExportPlugin>>,
base: Base<EditorPlugin>,
}

#[godot_api]
impl IEditorPlugin for FluentEditorPlugin {
fn enter_tree(&mut self) {
let export_plugin = FluentExportPlugin::new_gd();
self.export_plugin = Some(export_plugin.clone());
self.base_mut().add_export_plugin(export_plugin);
}

fn exit_tree(&mut self) {
let export_plugin = self.export_plugin.take();
self.base_mut().remove_export_plugin(export_plugin);
self.export_plugin = None;
}
}
47 changes: 47 additions & 0 deletions rust/src/fluent/export_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use godot::{classes::{EditorExportPlatform, EditorExportPlugin, IEditorExportPlugin}, prelude::*};
use constcat::concat as constcat;

use super::strip_comments;

const EXPORT_OPTION_PREFIX: &str = "fluent/";
const EXPORT_OPTION_STRIP_COMMENTS: &str = constcat!(EXPORT_OPTION_PREFIX, "strip_comments");

#[derive(GodotClass)]
#[class(base=EditorExportPlugin)]
pub struct FluentExportPlugin {
base: Base<EditorExportPlugin>,
}

#[godot_api]
impl IEditorExportPlugin for FluentExportPlugin {
fn init(base: Base<EditorExportPlugin>) -> Self {
Self {
base,
}
}

fn get_export_options(&self, _platform: Gd<EditorExportPlatform>) -> Array<Dictionary> {
array![dict! {
"option": dict! {
"name": GString::from(EXPORT_OPTION_STRIP_COMMENTS),
"type": VariantType::BOOL,
},
"default_value": Variant::from(true),
}]
}

fn export_file(&mut self, path: GString, _type: GString, _features: PackedStringArray) {
if !path.to_string().to_lowercase().ends_with("ftl") {
return;
}

if self.base().get_option(StringName::from(EXPORT_OPTION_STRIP_COMMENTS)).booleanize() {
// Strip comments from file
let contents = strip_comments(path.clone());
let binary = PackedByteArray::from_iter(contents.bytes());

self.base_mut().skip();
self.base_mut().add_file(path, binary, false);
}
}
}
6 changes: 3 additions & 3 deletions rust/src/fluent/extractor_packed_scene.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::collections::{HashMap, HashSet};

use godot::engine::node::AutoTranslateMode;
use godot::engine::{ClassDb, RegEx};
use godot::engine::{resource_loader::CacheMode, ResourceLoader};
use godot::classes::{ClassDb, RegEx, ResourceLoader};
use godot::classes::node::AutoTranslateMode;
use godot::classes::resource_loader::CacheMode;
use godot::prelude::*;

use super::{FluentTranslationParser, MessageGeneration};
Expand Down
6 changes: 4 additions & 2 deletions rust/src/fluent/generator.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use godot::{engine::{utilities::error_string, ProjectSettings, RegEx, RegExMatch}, prelude::*};
use godot::prelude::*;
use godot::classes::{ProjectSettings, RegEx, RegExMatch};
use godot::global::error_string;
use itertools::Itertools;
use std::{collections::HashMap, path::PathBuf};
use fluent_syntax::{ast, parser::parse};
use fluent_syntax::serializer::serialize;

use crate::utils::{create_or_open_file_for_read_write, get_files_recursive};
use godot::engine::global::Error as GdErr;
use godot::global::Error as GdErr;

use super::{project_settings::{INVALID_MESSAGE_HANDLING_SKIP, PROJECT_SETTING_GENERATOR_INVALID_MESSAGE_HANDLING, PROJECT_SETTING_GENERATOR_LOCALES, PROJECT_SETTING_GENERATOR_PATTERNS}, FluentPackedSceneTranslationParser, FluentTranslationParser};

Expand Down
7 changes: 4 additions & 3 deletions rust/src/fluent/global.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use godot::{engine::ResourceLoader, prelude::*};
use godot::prelude::*;
use godot::classes::ResourceLoader;

use super::ResourceFormatLoaderFluent;

Expand All @@ -12,10 +13,10 @@ impl FluentI18nSingleton {
pub(crate) const SINGLETON_NAME: &'static str = "FluentI18nSingleton";

pub(crate) fn register(&self) {
ResourceLoader::singleton().add_resource_format_loader(self.loader.clone().upcast());
ResourceLoader::singleton().add_resource_format_loader(self.loader.clone());
}

pub(crate) fn unregister(&self) {
ResourceLoader::singleton().remove_resource_format_loader(self.loader.clone().upcast());
ResourceLoader::singleton().remove_resource_format_loader(self.loader.clone());
}
}
5 changes: 3 additions & 2 deletions rust/src/fluent/importer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::path::PathBuf;

use godot::{engine::{FileAccess, IResourceFormatLoader, ProjectSettings, RegEx, ResourceFormatLoader}, prelude::*};
use godot::engine::global::Error as GdErr;
use godot::prelude::*;
use godot::classes::{FileAccess, IResourceFormatLoader, ProjectSettings, RegEx, ResourceFormatLoader};
use godot::global::Error as GdErr;

use super::{locale::{compute_locale, compute_message_pattern}, project_settings::*, TranslationFluent};

Expand Down
2 changes: 1 addition & 1 deletion rust/src/fluent/locale.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::{self, PathBuf};

use godot::engine::{ProjectSettings, RegEx, RegExMatch};
use godot::classes::{ProjectSettings, RegEx, RegExMatch};
use godot::prelude::*;
use unic_langid::LanguageIdentifier;

Expand Down
5 changes: 5 additions & 0 deletions rust/src/fluent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ mod importer;
pub use self::importer::*;
mod translation;
pub use self::translation::*;
mod export_plugin;
pub use self::export_plugin::*;
mod strip_comments;
pub use self::strip_comments::*;
pub mod locale;
#[allow(dead_code)]
pub mod project_settings;
mod editor_plugin;
4 changes: 2 additions & 2 deletions rust/src/fluent/project_settings.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use godot::engine::global::PropertyHint;
use godot::global::PropertyHint;
use godot::prelude::*;
use godot::engine::ProjectSettings;
use godot::classes::ProjectSettings;
use constcat::concat as constcat;

const PROJECT_SETTING_PREFIX: &str = "internationalization/fluent/";
Expand Down
25 changes: 25 additions & 0 deletions rust/src/fluent/strip_comments.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use godot::prelude::*;
use fluent_syntax::{ast, parser::parse, serializer::serialize};
use godot::classes::FileAccess;

pub fn strip_comments(path: GString) -> String {
let contents = FileAccess::get_file_as_string(path.clone());
let ftl = parse(contents.to_string());
let mut ftl = match ftl {
Ok(ftl) => ftl,
Err((ftl, err)) => {
godot_warn!("Error parsing {}: {:?}", path, err);
ftl
},
};

ftl.body.retain(|ast| {
match ast {
ast::Entry::Comment(_) | ast::Entry::GroupComment(_) | ast::Entry::ResourceComment(_) => false,
_ => true,
}
});

let contents = serialize(&ftl);
contents
}
Loading