From 42f12cb084122fb294e6bf7166190b332bee1c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Fam=C3=A0?= Date: Thu, 28 Sep 2023 20:55:24 +0200 Subject: [PATCH] Refactoring and bug fixes --- .github/workflows/build_all.yml | 14 +- README.md | 2 +- addons/FMOD/editor/editor_addon.gd | 111 ------ .../FMOD/editor/inspector_browser_plugin.gd | 39 --- addons/FMOD/fmod.gd | 23 +- addons/FMOD/native/fmod.gdextension | 9 + addons/FMOD/native/src/api/studio_api.cpp | 26 +- addons/FMOD/native/src/api/studio_api.h | 24 +- addons/FMOD/native/src/editor/fmod_plugin.h | 105 ++++++ .../native/src/editor/inspector_browser.cpp | 181 +++++++--- .../native/src/editor/inspector_browser.h | 166 +++++---- .../native/src/editor/project_browser.cpp | 139 ++++---- .../FMOD/native/src/editor/project_browser.h | 36 +- .../studio_event_emitter_3d_gizmo_plugin.cpp | 5 +- .../studio_event_emitter_3d_gizmo_plugin.h | 5 + .../native/src/fmod_studio_editor_module.cpp | 316 ++++++++++-------- .../native/src/fmod_studio_editor_module.h | 4 + addons/FMOD/native/src/misc/fmod_io.h | 1 - addons/FMOD/native/src/register_types.cpp | 28 +- addons/FMOD/native/src/register_types.h | 1 + ...ime_manager.gd => fmod_runtime_manager.gd} | 12 +- addons/FMOD/tests/fmod_test_framework.gd | 2 +- addons/FMOD/tests/test_studiosystem.gd | 8 +- 23 files changed, 671 insertions(+), 586 deletions(-) delete mode 100644 addons/FMOD/editor/editor_addon.gd delete mode 100644 addons/FMOD/editor/inspector_browser_plugin.gd create mode 100644 addons/FMOD/native/src/editor/fmod_plugin.h rename addons/FMOD/runtime/{runtime_manager.gd => fmod_runtime_manager.gd} (95%) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 46a9498..c4b896d 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -9,10 +9,10 @@ on: - main env: - FMOD_VERSION: 20214 - GODOT_ENGINE_VERSION: "4.1" + FMOD_VERSION: 20217 + GODOT_ENGINE_VERSION: "4.1.1" GODOT_ENGINE_STAGE: "stable" - INTEGRATION_VERSION: "1.0-alpha-2" + INTEGRATION_VERSION: "1.0-alpha-4" jobs: build-all: @@ -123,12 +123,8 @@ jobs: cd addons/FMOD/native/tools python download_fmod.py ${{ secrets.FMOD_USERNAME }} ${{ secrets.FMOD_PASSWORD }} api ${{ matrix.api-platform }} ${{ env.FMOD_VERSION }} mkdir -p ../fmodapi - if [ "${{ env.FMOD_VERSION }}" = "20214" ]; then - tar -zxvf fmodstudioapi${{env.FMOD_VERSION}}${{matrix.fmod-executable-suffix}} - tar -zxvf fmodstudioapi${{env.FMOD_VERSION}}${{matrix.fmod-executable-suffix}} --strip-components=1 -C ../fmodapi - else - tar -zxvf fmodstudioapi${{env.FMOD_VERSION}}${{matrix.fmod-executable-suffix}} --strip-components=1 -C ../fmodapi - fi + tar -zxvf fmodstudioapi${{env.FMOD_VERSION}}${{matrix.fmod-executable-suffix}} + tar -zxvf fmodstudioapi${{env.FMOD_VERSION}}${{matrix.fmod-executable-suffix}} --strip-components=1 -C ../fmodapi cd ../../../../ - name: Download FMOD API (iOS) diff --git a/README.md b/README.md index 9f1c4a5..96e0ef4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build](https://github.com/alessandrofama/fmod-for-godot/workflows/Build/badge.svg)](https://github.com/alessandrofama/fmod-for-godot/actions/workflows/build_all.yml) [![Discord](https://img.shields.io/discord/1083520667451920394?label=Discord)](https://discord.gg/XQbvRdQcNn) -Welcome! This repository provides an integration of [FMOD Studio's audio middleware](https://www.fmod.com/) into the [Godot game engine](https://godotengine.org). At the moment, **FMOD version 2.02.12** and **Godot 4.0 stable** are supported. +Welcome! This repository provides an integration of [FMOD Studio's audio middleware](https://www.fmod.com/) into the [Godot game engine](https://godotengine.org). At the moment, **FMOD version 2.02.17** and **Godot 4.1.1 stable** are supported. diff --git a/addons/FMOD/editor/editor_addon.gd b/addons/FMOD/editor/editor_addon.gd deleted file mode 100644 index e14dd25..0000000 --- a/addons/FMOD/editor/editor_addon.gd +++ /dev/null @@ -1,111 +0,0 @@ -@tool -extends EditorPlugin - -# Plugins -var inspector_browser: EditorInspectorPlugin -var studio_event_emitter_3d_gizmo_plugin: EditorNode3DGizmoPlugin - -# Icon for the custom nodes -var fmod_icon: Texture2D - -# Project Browser in the Toolbar -var project_preview_browser: Window -var project_preview_button: Button - -var banks_loaded_timer: Timer - - -func _enter_tree(): - # Create all icons - create_icons() - - fmod_icon = FMODStudioEditorModule.get_icon(FMODStudioEditorModule.FMOD_ICONTYPE_PROJECT) - - # Set up the icons for the custom nodes - # note(alex): This is very slow and results in a slower editor start - setup_custom_nodes_icon() - - # Add the inspector browser plugin to Godot. Until godot-cpp#886 is fixed - # we need to implement this in GDScript - inspector_browser = load("res://addons/FMOD/editor/inspector_browser_plugin.gd").new() - add_inspector_plugin(inspector_browser) - - # Add the Gizmo plugin for the StudioEventEmitter3D Node to Godot. Not possible - # from godot-cpp directly - studio_event_emitter_3d_gizmo_plugin = StudioEventEmitter3DGizmoPlugin.new() - add_node_3d_gizmo_plugin(studio_event_emitter_3d_gizmo_plugin) - - # Add the Project Browser Button to the Container Toolbar - project_preview_button = ProjectBrowserPreviewButton.new() - project_preview_browser = ProjectBrowserWindow.new() - var editor_scale = get_editor_interface().get_editor_scale() - project_preview_browser.set_editor_scale(editor_scale) - project_preview_browser.initialize() - add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, project_preview_button) - - if project_preview_button.get_child_count() == 0: - project_preview_button.add_child(project_preview_browser) - project_preview_browser.set_visible(false) - - # Set the Project Browser visible when pressed - project_preview_button.connect("pressed", - func(): - if project_preview_browser.visible == false: - project_preview_browser.popup_centered() - else: - project_preview_browser.set_visible(false)) - -func _exit_tree(): - remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR, project_preview_button) - remove_inspector_plugin(inspector_browser) - remove_node_3d_gizmo_plugin(studio_event_emitter_3d_gizmo_plugin) - - -func create_icons(): - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/fmod_icon.svg", - FMODStudioEditorModule.FMOD_ICONTYPE_PROJECT - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/folder_closed.svg", - FMODStudioEditorModule.FMOD_ICONTYPE_FOLDER_CLOSED - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/folder_opened.svg", - FMODStudioEditorModule.FMOD_ICONTYPE_FOLDER_OPENED - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/event_icon.svg", FMODStudioEditorModule.FMOD_ICONTYPE_EVENT - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/bank_icon.svg", FMODStudioEditorModule.FMOD_ICONTYPE_BANK - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/snapshot_icon.svg", - FMODStudioEditorModule.FMOD_ICONTYPE_SNAPSHOT - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/bus_icon.svg", FMODStudioEditorModule.FMOD_ICONTYPE_BUS - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/vca_icon.svg", FMODStudioEditorModule.FMOD_ICONTYPE_VCA - ) - FMODStudioEditorModule.create_icon( - "res://addons/FMOD/editor/images/c_parameter_icon.svg", - FMODStudioEditorModule.FMOD_ICONTYPE_C_PARAMETER - ) - - -func setup_custom_nodes_icon(): - # note(alex): Directly setting the icons on the theme slows down startup time - # considerably. We duplicate the theme to avoid this here. - var theme := get_editor_interface().get_base_control().get_theme().duplicate() - if theme: - theme.set_icon(&"StudioEventEmitter3D", &"EditorIcons", fmod_icon) - theme.set_icon(&"StudioEventEmitter2D", &"EditorIcons", fmod_icon) - theme.set_icon(&"StudioParameterTrigger", &"EditorIcons", fmod_icon) - theme.set_icon(&"StudioGlobalParameterTrigger", &"EditorIcons", fmod_icon) - theme.set_icon(&"StudioBankLoader", &"EditorIcons", fmod_icon) - theme.set_icon(&"StudioListener3D", &"EditorIcons", fmod_icon) - theme.set_icon(&"StudioListener2D", &"EditorIcons", fmod_icon) - get_editor_interface().get_base_control().set_theme(theme) diff --git a/addons/FMOD/editor/inspector_browser_plugin.gd b/addons/FMOD/editor/inspector_browser_plugin.gd deleted file mode 100644 index 45a912c..0000000 --- a/addons/FMOD/editor/inspector_browser_plugin.gd +++ /dev/null @@ -1,39 +0,0 @@ -# note(alex): Due to a godot-cpp bug we need to create the InspectorPlugin here -# in GDScript. See godot-cpp#886 - -extends EditorInspectorPlugin - - -func _can_handle(object): - return object != null - - -func _parse_property(object, type, name, hint_type, hint_string, usage_flags, wide): - if object != null && type == TYPE_OBJECT: - if hint_string == "BankAsset": - var inspector_property: InspectorBrowserProperty = InspectorBrowserProperty.new() - inspector_property.init(FMODStudioEditorModule.FMOD_ASSETTYPE_BANK) - add_property_editor(name, inspector_property) - return true - elif hint_string == "EventAsset": - var inspector_property: InspectorBrowserProperty = InspectorBrowserProperty.new() - inspector_property.init(FMODStudioEditorModule.FMOD_ASSETTYPE_EVENT) - add_property_editor(name, inspector_property) - return true - elif hint_string == "BusAsset": - var inspector_property: InspectorBrowserProperty = InspectorBrowserProperty.new() - inspector_property.init(FMODStudioEditorModule.FMOD_ASSETTYPE_BUS) - add_property_editor(name, inspector_property) - return true - elif hint_string == "VCAAsset": - var inspector_property: InspectorBrowserProperty = InspectorBrowserProperty.new() - inspector_property.init(FMODStudioEditorModule.FMOD_ASSETTYPE_VCA) - add_property_editor(name, inspector_property) - return true - elif hint_string == "ParameterAsset": - var inspector_property: InspectorBrowserProperty = InspectorBrowserProperty.new() - inspector_property.init(FMODStudioEditorModule.FMOD_ASSETTYPE_GLOBAL_PARAMETER) - add_property_editor(name, inspector_property) - return true - return false - return false diff --git a/addons/FMOD/fmod.gd b/addons/FMOD/fmod.gd index 9a6d3d3..96ce68b 100644 --- a/addons/FMOD/fmod.gd +++ b/addons/FMOD/fmod.gd @@ -1,23 +1,2 @@ @tool -extends EditorPlugin - -var editor_addon: EditorPlugin - - -func _enter_tree(): - if !ProjectSettings.has_setting("autoload/RuntimeManager"): - add_autoload_singleton("RuntimeManager", "res://addons/FMOD/runtime/runtime_manager.gd") - - # note(alex): _enter_tree is called twice here (bug?) so we check if we are already initialized - if !FMODStudioEditorModule.get_is_initialized(): - editor_addon = load("res://addons/FMOD/editor/editor_addon.gd").new() - get_editor_interface().get_base_control().add_child(editor_addon) - - FMODStudioEditorModule.set_is_initialized(true) - - -func _exit_tree(): - if FMODStudioEditorModule.get_is_initialized(): - get_editor_interface().get_base_control().remove_child(editor_addon) - editor_addon.queue_free() - remove_autoload_singleton("RuntimeManager") +extends EditorPlugin \ No newline at end of file diff --git a/addons/FMOD/native/fmod.gdextension b/addons/FMOD/native/fmod.gdextension index e11a4d1..3066af2 100644 --- a/addons/FMOD/native/fmod.gdextension +++ b/addons/FMOD/native/fmod.gdextension @@ -24,3 +24,12 @@ linux.debug = {"lib/linux/debug/libfmodL.so": "", "lib/linux/debug/libfmodL.so.1 linux.release = {"lib/linux/release/libfmod.so": "", "lib/linux/release/libfmod.so.13": "", "lib/linux/release/libfmod.so.13.12": "", "lib/linux/release/libfmodstudio.so": "", "lib/linux/release/libfmodstudio.so.13": "", "lib/linux/release/libfmodstudio.so.13.12": ""} android.debug.arm64 = {"lib/android/arm64/debug/libfmodL.so": "", "lib/android/arm64/debug/libfmodstudioL.so": ""} android.release.arm64 = {"lib/android/arm64/release/libfmodL.so": "", "lib/android/arm64/release/libfmodstudioL.so": ""} + +[icons] +StudioEventEmitter3D = "res://addons/FMOD/editor/images/fmod_icon.svg" +StudioEventEmitter2D = "res://addons/FMOD/editor/images/fmod_icon.svg" +StudioParameterTrigger = "res://addons/FMOD/editor/images/fmod_icon.svg" +StudioGlobalParameterTrigger = "res://addons/FMOD/editor/images/fmod_icon.svg" +StudioBankLoader = "res://addons/FMOD/editor/images/fmod_icon.svg" +StudioListener3D = "res://addons/FMOD/editor/images/fmod_icon.svg" +StudioListener2D = "res://addons/FMOD/editor/images/fmod_icon.svg" \ No newline at end of file diff --git a/addons/FMOD/native/src/api/studio_api.cpp b/addons/FMOD/native/src/api/studio_api.cpp index 9b1a2b2..d1ae394 100644 --- a/addons/FMOD/native/src/api/studio_api.cpp +++ b/addons/FMOD/native/src/api/studio_api.cpp @@ -27,16 +27,16 @@ void StudioSystem::_bind_methods() &StudioSystem::get_parameter_label_by_id); ClassDB::bind_method(D_METHOD("get_parameter_by_id", "parameter_id"), &StudioSystem::get_parameter_by_id); ClassDB::bind_method(D_METHOD("set_parameter_by_id", "parameter_id", "value", "ignore_seek_speed"), - &StudioSystem::set_parameter_by_id); + &StudioSystem::set_parameter_by_id, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_parameter_by_id_with_label", "parameter_id", "label", "ignore_seek_speed"), - &StudioSystem::set_parameter_by_id_with_label); + &StudioSystem::set_parameter_by_id_with_label, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_parameters_by_ids", "parameter_ids", "values", "count", "ignore_seek_speed"), - &StudioSystem::set_parameters_by_ids); + &StudioSystem::set_parameters_by_ids, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_parameter_by_name", "name"), &StudioSystem::get_parameter_by_name); ClassDB::bind_method(D_METHOD("set_parameter_by_name", "name", "value", "ignore_seek_speed"), - &StudioSystem::set_parameter_by_name); + &StudioSystem::set_parameter_by_name, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_parameter_by_name_with_label", "name", "label", "ignore_seek_speed"), - &StudioSystem::set_parameter_by_name_with_label); + &StudioSystem::set_parameter_by_name_with_label, DEFVAL(false)); ClassDB::bind_method(D_METHOD("lookup_id", "path"), &StudioSystem::lookup_id); ClassDB::bind_method(D_METHOD("lookup_path", "guid"), &StudioSystem::lookup_path); ClassDB::bind_method(D_METHOD("get_num_listeners"), &StudioSystem::get_num_listeners); @@ -1261,16 +1261,16 @@ void EventInstance::_bind_methods() ClassDB::bind_method(D_METHOD("is_virtual"), &EventInstance::is_virtual); ClassDB::bind_method(D_METHOD("get_parameter_by_id", "parameter_id"), &EventInstance::get_parameter_by_id); ClassDB::bind_method(D_METHOD("set_parameter_by_id", "parameter_id", "parameter_value", "ignore_seek_speed"), - &EventInstance::set_parameter_by_id); + &EventInstance::set_parameter_by_id, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_parameter_by_id_with_label", "parameter_id", "label", "ignore_seek_speed"), - &EventInstance::set_parameter_by_id_with_label); + &EventInstance::set_parameter_by_id_with_label, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_parameters_by_ids", "parameter_ids", "values", "count", "ignore_seek_speed"), - &EventInstance::set_parameters_by_ids); + &EventInstance::set_parameters_by_ids, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_parameter_by_name", "name"), &EventInstance::get_parameter_by_name); ClassDB::bind_method(D_METHOD("set_parameter_by_name", "name", "parameter_value", "ignore_seek_speed"), - &EventInstance::set_parameter_by_name); + &EventInstance::set_parameter_by_name, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_parameter_by_name_with_label", "name", "label", "ignore_seek_speed"), - &EventInstance::set_parameter_by_name_with_label); + &EventInstance::set_parameter_by_name_with_label, DEFVAL(false)); ClassDB::bind_method(D_METHOD("key_off"), &EventInstance::key_off); ClassDB::bind_method(D_METHOD("get_cpu_usage", "cpu_usage"), &EventInstance::get_cpu_usage); ClassDB::bind_method(D_METHOD("get_memory_usage", "memory_usage_ref"), &EventInstance::get_memory_usage); @@ -1449,7 +1449,7 @@ bool EventInstance::start() const return ERROR_CHECK(event_instance->start()); } -bool EventInstance::stop(int stop_mode) const +bool EventInstance::stop(FMOD_STUDIO_STOP_MODE stop_mode) const { return ERROR_CHECK(event_instance->stop(static_cast(stop_mode))); } @@ -1550,7 +1550,7 @@ bool EventInstance::set_parameter_by_id(const Ref& parameter_id, - const String& label, bool ignore_seek_speed) + const String& label, bool ignore_seek_speed) const { FMOD_STUDIO_PARAMETER_ID id; parameter_id->get_parameter_id(id); @@ -1599,7 +1599,7 @@ bool EventInstance::set_parameter_by_name(const String& name, float value, bool return ERROR_CHECK(event_instance->setParameterByName(name.utf8().get_data(), value, ignore_seek_speed)); } -bool EventInstance::set_parameter_by_name_with_label(const String& name, const String& label, bool ignore_seek_speed) +bool EventInstance::set_parameter_by_name_with_label(const String& name, const String& label, bool ignore_seek_speed) const { return ERROR_CHECK(event_instance->setParameterByNameWithLabel(name.utf8().get_data(), label.utf8().get_data(), ignore_seek_speed)); diff --git a/addons/FMOD/native/src/api/studio_api.h b/addons/FMOD/native/src/api/studio_api.h index ec98fdf..e14a670 100644 --- a/addons/FMOD/native/src/api/studio_api.h +++ b/addons/FMOD/native/src/api/studio_api.h @@ -40,7 +40,7 @@ class StudioSystem : public RefCounted Ref get_event_by_id(const String& event_guid) const; Ref get_bus_by_id(const String& bus_guid) const; Ref get_vca_by_id(const String& vca_guid) const; - Ref get_bank_by_id(const String& bankGuid) const; + Ref get_bank_by_id(const String& bank_guid) const; // note(alex): StudioSystem::getSoundInfo is not implemented due to missing Core API implementation. Ref get_parameter_description_by_name(const String& name) const; @@ -51,14 +51,14 @@ class StudioSystem : public RefCounted Dictionary get_parameter_by_id(const Ref& parameter_id) const; bool set_parameter_by_id(const Ref& parameter_id, float value, - bool ignore_seek_speed) const; + bool ignore_seek_speed = false) const; bool set_parameter_by_id_with_label(const Ref& parameter_id, const String& label, - bool ignore_seek_speed) const; + bool ignore_seek_speed = false) const; bool set_parameters_by_ids(const Array& parameter_ids, const Array& values, int count, - bool ignore_seek_speed) const; + bool ignore_seek_speed = false) const; Dictionary get_parameter_by_name(const String& name) const; - bool set_parameter_by_name(const String& name, float value, bool ignore_seek_speed) const; - bool set_parameter_by_name_with_label(const String& name, const String& label, bool ignore_seek_speed) const; + bool set_parameter_by_name(const String& name, float value, bool ignore_seek_speed = false) const; + bool set_parameter_by_name_with_label(const String& name, const String& label, bool ignore_seek_speed = false) const; String lookup_id(const String& path) const; String lookup_path(const String& guid) const; @@ -187,7 +187,7 @@ class EventInstance : public RefCounted bool set_paused(bool paused) const; bool start() const; - bool stop(int stop_mode) const; + bool stop(FMOD_STUDIO_STOP_MODE stop_mode) const; int get_timeline_position() const; bool set_timeline_position(int position) const; @@ -203,14 +203,14 @@ class EventInstance : public RefCounted Dictionary get_parameter_by_id(const Ref& parameter_id) const; bool set_parameter_by_id(const Ref& parameter_id, float value, - bool ignore_seek_speed) const; + bool ignore_seek_speed = false) const; bool set_parameter_by_id_with_label(const Ref& parameter_id, - const String& label, bool ignore_seek_speed); - bool set_parameters_by_ids(const Array ids, const Array values, int count, bool ignore_seek_speed) const; + const String& label, bool ignore_seek_speed = false) const; + bool set_parameters_by_ids(const Array ids, const Array values, int count, bool ignore_seek_speed = false) const; Dictionary get_parameter_by_name(const String& name) const; - bool set_parameter_by_name(const String& name, float value, bool ignore_seek_speed) const; - bool set_parameter_by_name_with_label(const String& name, const String& label, bool ignore_seek_speed); + bool set_parameter_by_name(const String& name, float value, bool ignore_seek_speed = false) const; + bool set_parameter_by_name_with_label(const String& name, const String& label, bool ignore_seek_speed = false) const; bool key_off() const; diff --git a/addons/FMOD/native/src/editor/fmod_plugin.h b/addons/FMOD/native/src/editor/fmod_plugin.h new file mode 100644 index 0000000..82ca8bd --- /dev/null +++ b/addons/FMOD/native/src/editor/fmod_plugin.h @@ -0,0 +1,105 @@ +#ifndef FMOD_PLUGIN +#define FMOD_PLUGIN + +#include "fmod_studio_editor_module.h" +#include "inspector_browser.h" +#include "project_browser.h" +#include "studio_event_emitter_3d_gizmo_plugin.h" +#include +#include + +class FMODEditorPlugin : public EditorPlugin +{ + GDCLASS(FMODEditorPlugin, EditorPlugin); + +protected: + static void _bind_methods() + { + ClassDB::bind_method(D_METHOD("on_project_browser_button_pressed"), &FMODEditorPlugin::on_project_browser_button_pressed); + } + +private: + Ref gizmo_plugin; + Ref inspector_plugin; + FMODProjectBrowserWindow* project_preview_browser; + FMODProjectBrowserPreviewButton* project_preview_button; + +public: + virtual void _enter_tree() override + { + if (!ProjectSettings::get_singleton()->has_setting("autoload/FMODRuntime")) + { + add_autoload_singleton("FMODRuntime", "res://addons/FMOD/runtime/fmod_runtime_manager.gd"); + } + + FMODSettings* fmod_settings = FMODSettings::get_singleton(); + fmod_settings->initialize(); + + FMODStudioEditorModule* fmod_editor = FMODStudioEditorModule::get_singleton(); + + // Create Icons + if (fmod_editor) + { + fmod_editor->create_icon("res://addons/FMOD/editor/images/fmod_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_PROJECT); + fmod_editor->create_icon("res://addons/FMOD/editor/images/folder_closed.svg", FMODStudioEditorModule::FMOD_ICONTYPE_FOLDER_CLOSED); + fmod_editor->create_icon("res://addons/FMOD/editor/images/folder_opened.svg", FMODStudioEditorModule::FMOD_ICONTYPE_FOLDER_OPENED); + fmod_editor->create_icon("res://addons/FMOD/editor/images/event_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_EVENT); + fmod_editor->create_icon("res://addons/FMOD/editor/images/bank_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_BANK); + fmod_editor->create_icon("res://addons/FMOD/editor/images/snapshot_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_SNAPSHOT); + fmod_editor->create_icon("res://addons/FMOD/editor/images/bus_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_BUS); + fmod_editor->create_icon("res://addons/FMOD/editor/images/vca_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_VCA); + fmod_editor->create_icon("res://addons/FMOD/editor/images/c_parameter_icon.svg", FMODStudioEditorModule::FMOD_ICONTYPE_C_PARAMETER); + } + + // Init Project Browser + project_preview_browser = memnew(FMODProjectBrowserWindow); + float editor_scale = get_editor_interface()->get_editor_scale(); + project_preview_browser->set_editor_scale(editor_scale); + project_preview_browser->initialize(); + + // Add the Project Browser Button to the Container Toolbar + project_preview_button = memnew(FMODProjectBrowserPreviewButton); + project_preview_button->initialize(); + add_control_to_container(EditorPlugin::CONTAINER_TOOLBAR, project_preview_button); + + if (project_preview_button->get_child_count() == 0) + { + project_preview_button->add_child(project_preview_browser); + project_preview_browser->set_visible(false); + } + + // Set the Project Browser visible when pressed + project_preview_button->connect("pressed", Callable(this, "on_project_browser_button_pressed")); + + gizmo_plugin.instantiate(); + add_node_3d_gizmo_plugin(gizmo_plugin); + + inspector_plugin.instantiate(); + inspector_plugin->set_editor_scale(editor_scale); + add_inspector_plugin(inspector_plugin); + } + + virtual void _exit_tree() override + { + remove_autoload_singleton("FMODRuntime"); + remove_control_from_container(EditorPlugin::CONTAINER_TOOLBAR, project_preview_button); + project_preview_button->queue_free(); + remove_node_3d_gizmo_plugin(gizmo_plugin); + remove_inspector_plugin(inspector_plugin); + project_preview_browser->queue_free(); + } + + void on_project_browser_button_pressed() + { + if (!project_preview_browser->is_visible()) + { + project_preview_browser->popup_centered(); + } + else + { + project_preview_browser->set_visible(false); + } + } +}; + +#endif \ No newline at end of file diff --git a/addons/FMOD/native/src/editor/inspector_browser.cpp b/addons/FMOD/native/src/editor/inspector_browser.cpp index fbcb536..a9792b8 100644 --- a/addons/FMOD/native/src/editor/inspector_browser.cpp +++ b/addons/FMOD/native/src/editor/inspector_browser.cpp @@ -1,18 +1,21 @@ #include "inspector_browser.h" +#include using namespace godot; -void InspectorBrowserTree::_bind_methods() +const int BASE_DPI = 96; + +void FMODEditorInspectorTree::_bind_methods() { - ClassDB::bind_method(D_METHOD("on_size_changed"), &InspectorBrowserTree::on_size_changed); - ClassDB::bind_method(D_METHOD("on_item_collapsed"), &InspectorBrowserTree::on_item_collapsed); - ClassDB::bind_method(D_METHOD("on_text_changed"), &InspectorBrowserTree::on_text_changed); + ClassDB::bind_method(D_METHOD("on_size_changed"), &FMODEditorInspectorTree::on_size_changed); + ClassDB::bind_method(D_METHOD("on_item_collapsed"), &FMODEditorInspectorTree::on_item_collapsed); + ClassDB::bind_method(D_METHOD("on_text_changed"), &FMODEditorInspectorTree::on_text_changed); } -void InspectorBrowserTree::initialize(FMODStudioEditorModule::FMODAssetType item_type) +void FMODEditorInspectorTree::initialize(FMODStudioEditorModule::FMODAssetType item_type) { type = item_type; - window = Object::cast_to(get_parent()->get_parent()); + window = Object::cast_to(get_parent()->get_parent()); window->connect("size_changed", Callable(this, "on_size_changed")); search_text = window->search_text; @@ -29,7 +32,7 @@ void InspectorBrowserTree::initialize(FMODStudioEditorModule::FMODAssetType item } } -void InspectorBrowserTree::populate_browser() +void FMODEditorInspectorTree::populate_browser() { if (root_item) { @@ -111,6 +114,68 @@ void InspectorBrowserTree::populate_browser() FMODStudioEditorModule::get_singleton()->create_tree_items(this, project_cache->get_parameter_tree(), parameters_root); parameters_root->set_visible(true); + + // Setup local parameters + { + local_parameters_root = create_item(root_item); + local_parameters_root->set_text(0, "Local Parameters"); + local_parameters_root->set_icon( + 0, FMODStudioEditorModule::get_singleton()->get_icon(FMODStudioEditorModule::FMOD_ICONTYPE_FOLDER_CLOSED)); + FMODStudioEditorModule::get_singleton()->create_tree_items(this, project_cache->get_event_tree(), + local_parameters_root); + local_parameters_root->set_visible(true); + + // note(alex): iterating through the Event Tree to get local Event Parameters and adding them as children to the respective Events + std::function get_event_parameters = [&get_event_parameters](TreeItem* tree_item) + { + while (tree_item) + { + if (tree_item->has_meta("Type")) + { + String type = tree_item->get_meta("Type"); + if (type == String("event")) + { + Ref event_asset = tree_item->get_meta("Resource"); + + if (event_asset.is_valid()) + { + // note(alex): setting the Resource meta for the Event TreeItem to null, so it can't be selected + tree_item->set_meta("Resource", Variant()); + + Dictionary parameters = event_asset->get_parameters(); + + for (size_t i = 0; i < parameters.size(); i++) + { + Ref param_asset = parameters.values()[i]; + + if (param_asset.is_valid()) + { + String name = param_asset->get_name(); + String path = param_asset->get_path(); + TreeItem* child = tree_item->create_child(); + child->set_text(0, name); + child->set_icon(0, FMODStudioEditorModule::get_singleton()->get_icon(FMODStudioEditorModule::FMOD_ICONTYPE_C_PARAMETER)); + child->set_meta("Type", "parameter"); + child->set_meta("Path", path); + child->set_meta("Resource", param_asset); + } + } + } + } + } + + if (tree_item->get_child_count() > 0) + { + get_event_parameters(tree_item->get_first_child()); + } + + tree_item = tree_item->get_next(); + } + }; + + TreeItem* item = local_parameters_root->get_first_child(); + get_event_parameters(item); + } } break; default: @@ -119,13 +184,13 @@ void InspectorBrowserTree::populate_browser() } } -void InspectorBrowserTree::on_text_changed(const String& text_filter) +void FMODEditorInspectorTree::on_text_changed(const String& text_filter) { filter = text_filter; update_filter(root_item, false); } -bool InspectorBrowserTree::update_filter(TreeItem* p_parent, bool p_scroll_to_selected) +bool FMODEditorInspectorTree::update_filter(TreeItem* p_parent, bool p_scroll_to_selected) { if (!p_parent) { @@ -183,7 +248,7 @@ bool InspectorBrowserTree::update_filter(TreeItem* p_parent, bool p_scroll_to_se return keep; } -void InspectorBrowserTree::collapse_all(TreeItem* p_parent) +void FMODEditorInspectorTree::collapse_all(TreeItem* p_parent) { if (!p_parent) { @@ -253,12 +318,12 @@ void InspectorBrowserTree::collapse_all(TreeItem* p_parent) } } -void InspectorBrowserTree::on_size_changed() +void FMODEditorInspectorTree::on_size_changed() { window->root_vbox->set_size(window->get_size()); } -void InspectorBrowserTree::on_item_collapsed(Object* item) +void FMODEditorInspectorTree::on_item_collapsed(Object* item) { TreeItem* tree_item = Object::cast_to(item); @@ -285,19 +350,38 @@ void InspectorBrowserTree::on_item_collapsed(Object* item) } } -void InspectorBrowser::_bind_methods() +void FMODEditorInspector::_bind_methods() { } -void InspectorBrowser::initialize() +void FMODEditorInspector::initialize() { set_name("Window"); set_title("FMOD Browser"); set_disable_3d(true); + set_exclusive(true); root_vbox = memnew(VBoxContainer); root_vbox->set_name("ParentVBoxContainer"); - root_vbox->set_size(Size2(700, 1100)); + + Size2 window_size = Size2(400, 680); + DisplayServer* display_server = DisplayServer::get_singleton(); + + if (display_server) + { + int32_t dpi = display_server->screen_get_dpi(); + + if (dpi != 72) + { + int dpi_scaling_factor = 1; + dpi_scaling_factor = dpi / BASE_DPI; + window_size *= dpi_scaling_factor; + } + + window_size *= editor_scale; + } + + root_vbox->set_size(window_size); root_vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL); root_vbox->set_h_size_flags(Control::SIZE_EXPAND_FILL); add_child(root_vbox); @@ -310,7 +394,7 @@ void InspectorBrowser::initialize() search_text->set_name("SearchText"); search_vbox->add_child(search_text); - tree = memnew(InspectorBrowserTree); + tree = memnew(FMODEditorInspectorTree); tree->set_name("ProjectObjectsTree"); tree->set_allow_reselect(true); tree->set_hide_folding(true); @@ -320,20 +404,25 @@ void InspectorBrowser::initialize() root_vbox->add_child(tree); } -void InspectorBrowserProperty::_bind_methods() +void FMODEditorInspector::set_editor_scale(float editor_scale) +{ + this->editor_scale = editor_scale; +} + +void FMODEditorInspectorProperty::_bind_methods() { - ClassDB::bind_method(D_METHOD("init", "asset_type"), &InspectorBrowserProperty::init); - ClassDB::bind_method(D_METHOD("on_button_pressed"), &InspectorBrowserProperty::on_button_pressed); - ClassDB::bind_method(D_METHOD("on_item_selected"), &InspectorBrowserProperty::on_item_selected); - ClassDB::bind_method(D_METHOD("reset"), &InspectorBrowserProperty::reset); - ClassDB::bind_method(D_METHOD("on_event_popup_id_pressed", "id"), &InspectorBrowserProperty::on_event_popup_id_pressed); + ClassDB::bind_method(D_METHOD("init", "asset_type"), &FMODEditorInspectorProperty::init); + ClassDB::bind_method(D_METHOD("on_button_pressed"), &FMODEditorInspectorProperty::on_button_pressed); + ClassDB::bind_method(D_METHOD("on_item_selected"), &FMODEditorInspectorProperty::on_item_selected); + ClassDB::bind_method(D_METHOD("reset"), &FMODEditorInspectorProperty::reset); + ClassDB::bind_method(D_METHOD("on_event_popup_id_pressed", "id"), &FMODEditorInspectorProperty::on_event_popup_id_pressed); } -void InspectorBrowserProperty::popup_menu(PopupType type, Vector2 pos) +void FMODEditorInspectorProperty::popup_menu(PopupType type, Vector2 pos) { switch (type) { - case InspectorBrowserProperty::POPUP_EVENT: + case FMODEditorInspectorProperty::POPUP_EVENT: { event_popup->popup_on_parent(Rect2(pos, Vector2(0, 0))); } @@ -343,19 +432,20 @@ void InspectorBrowserProperty::popup_menu(PopupType type, Vector2 pos) } } -void InspectorBrowserProperty::init(FMODStudioEditorModule::FMODAssetType asset_type) +void FMODEditorInspectorProperty::init(FMODStudioEditorModule::FMODAssetType asset_type) { type = asset_type; property_control = memnew(Button); - inspector_browser = memnew(InspectorBrowser); + inspector_browser = memnew(FMODEditorInspector); + inspector_browser->set_editor_scale(editor_scale); inspector_browser->initialize(); add_child(property_control); property_control->set_clip_text(true); - inspector_browser->set_exclusive(true); + inspector_browser->connect("close_requested", Callable(this, "reset")); - inspector_browser->connect("focus_exited", Callable(this, "reset")); - InspectorBrowserTree* tree = inspector_browser->tree; + inspector_browser->connect("confirmed", Callable(this, "reset")); + FMODEditorInspectorTree* tree = inspector_browser->tree; tree->initialize(type); switch (type) @@ -396,7 +486,7 @@ void InspectorBrowserProperty::init(FMODStudioEditorModule::FMODAssetType asset_ event_popup->set_owner(this); } -void InspectorBrowserProperty::_input(const Ref& event) +void FMODEditorInspectorProperty::_input(const Ref& event) { Ref mouse_button_event = event; if (mouse_button_event.is_valid()) @@ -417,7 +507,7 @@ void InspectorBrowserProperty::_input(const Ref& event) } } -void InspectorBrowserProperty::_update_property() +void FMODEditorInspectorProperty::_update_property() { Variant new_value = get_edited_object()->get(get_edited_property()); @@ -483,7 +573,7 @@ void InspectorBrowserProperty::_update_property() updating = false; } -void InspectorBrowserProperty::on_button_pressed() +void FMODEditorInspectorProperty::on_button_pressed() { if (updating) { @@ -494,9 +584,9 @@ void InspectorBrowserProperty::on_button_pressed() open_popup(); } -void InspectorBrowserProperty::on_item_selected() +void FMODEditorInspectorProperty::on_item_selected() { - InspectorBrowserTree* tree = inspector_browser->tree; + FMODEditorInspectorTree* tree = inspector_browser->tree; TreeItem* selected_item = tree->get_selected(); if (selected_item) { @@ -522,18 +612,19 @@ void InspectorBrowserProperty::on_item_selected() } } -void InspectorBrowserProperty::open_popup() +void FMODEditorInspectorProperty::open_popup() { add_child(inspector_browser); + inspector_browser->popup( - Rect2i(Vector2i(get_global_mouse_position().x - 900.0f, get_global_mouse_position().y - 200.0f), Vector2(1, 1))); + Rect2i(Vector2i(get_global_mouse_position().x - (inspector_browser->get_size().x), get_global_mouse_position().y - (100.0f * editor_scale)), Vector2(1, 1))); } -void InspectorBrowserProperty::close_popup() +void FMODEditorInspectorProperty::close_popup() { for (int i = 0; i < get_child_count(); i++) { - if (get_child(i)->get_class() == "InspectorBrowser") + if (get_child(i)->get_class() == "FMODEditorInspector") { inspector_browser->hide(); remove_child(inspector_browser); @@ -543,12 +634,12 @@ void InspectorBrowserProperty::close_popup() inspector_browser->search_text->set_text(""); } -void InspectorBrowserProperty::reset() +void FMODEditorInspectorProperty::reset() { emit_changed(get_edited_property(), current_value); } -void InspectorBrowserProperty::on_event_popup_id_pressed(int32_t id) +void FMODEditorInspectorProperty::on_event_popup_id_pressed(int32_t id) { if (!current_value.is_valid()) { @@ -593,3 +684,13 @@ void InspectorBrowserProperty::on_event_popup_id_pressed(int32_t id) break; } } + +void FMODEditorInspectorProperty::set_editor_scale(float editor_scale) +{ + this->editor_scale = editor_scale; +} + +float FMODEditorInspectorProperty::get_editor_scale() const +{ + return editor_scale; +} diff --git a/addons/FMOD/native/src/editor/inspector_browser.h b/addons/FMOD/native/src/editor/inspector_browser.h index f9cc07b..a24faa8 100644 --- a/addons/FMOD/native/src/editor/inspector_browser.h +++ b/addons/FMOD/native/src/editor/inspector_browser.h @@ -3,6 +3,7 @@ #include "fmod_assets.h" #include "fmod_studio_editor_module.h" +#include #include #include #include @@ -15,15 +16,14 @@ #include #include #include -#include using namespace godot; -class InspectorBrowser; +class FMODEditorInspector; -class InspectorBrowserTree : public Tree +class FMODEditorInspectorTree : public Tree { - GDCLASS(InspectorBrowserTree, Tree); + GDCLASS(FMODEditorInspectorTree, Tree); protected: static void _bind_methods(); @@ -39,9 +39,10 @@ class InspectorBrowserTree : public Tree TreeItem* busses_root = nullptr; TreeItem* vcas_root = nullptr; TreeItem* parameters_root = nullptr; + TreeItem* local_parameters_root = nullptr; Ref icon; Ref project_cache; - InspectorBrowser* window = nullptr; + FMODEditorInspector* window = nullptr; String filter = ""; public: @@ -54,24 +55,28 @@ class InspectorBrowserTree : public Tree void on_item_collapsed(Object* item); }; -class InspectorBrowser : public Window +class FMODEditorInspector : public AcceptDialog { - GDCLASS(InspectorBrowser, Window); + GDCLASS(FMODEditorInspector, AcceptDialog); protected: static void _bind_methods(); +private: + float editor_scale; + public: VBoxContainer* root_vbox = nullptr; VBoxContainer* search_vbox = nullptr; LineEdit* search_text = nullptr; - InspectorBrowserTree* tree = nullptr; + FMODEditorInspectorTree* tree = nullptr; void initialize(); + void set_editor_scale(float editor_scale); }; -class InspectorBrowserProperty : public EditorProperty +class FMODEditorInspectorProperty : public EditorProperty { - GDCLASS(InspectorBrowserProperty, EditorProperty); + GDCLASS(FMODEditorInspectorProperty, EditorProperty); enum PopupType { @@ -94,9 +99,10 @@ class InspectorBrowserProperty : public EditorProperty Ref icon; Ref current_value; bool updating = false; - InspectorBrowser* inspector_browser; + FMODEditorInspector* inspector_browser; FMODStudioEditorModule::FMODAssetType type = FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_NONE; PopupMenu* event_popup; + float editor_scale; void popup_menu(PopupType type, Vector2 pos); public: @@ -109,70 +115,82 @@ class InspectorBrowserProperty : public EditorProperty void close_popup(); void reset(); void on_event_popup_id_pressed(int32_t id); + void set_editor_scale(float editor_scale); + float get_editor_scale() const; }; -//class InspectorBrowserPlugin : public EditorInspectorPlugin -//{ -// GDCLASS(InspectorBrowserPlugin, EditorInspectorPlugin); -// -//protected: -// static void _bind_methods() -// { -// } -// -//public: -// virtual bool _can_handle(const Variant& object) const override -// { -// Object* obj = object; -// return object.get_type() != Variant::NIL && obj != nullptr; -// } -// -// virtual bool _parse_property(Object* object, int64_t type, const String& name, int64_t hint_type, -// const String& hint_string, int64_t usage_flags, bool wide) override -// { -// if (object != nullptr && type == Variant::Type::OBJECT) -// { -// if (hint_string == "EventAsset") -// { -// InspectorBrowserProperty* control = memnew(InspectorBrowserProperty); -// control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_EVENT); -// add_property_editor(name, control); -// return true; -// } -// else if (hint_string == "BankAsset") -// { -// InspectorBrowserProperty* control = memnew(InspectorBrowserProperty); -// control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_BANK); -// add_property_editor(name, control); -// return true; -// } -// else if (hint_string == "BusAsset") -// { -// InspectorBrowserProperty* control = memnew(InspectorBrowserProperty); -// control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_BUS); -// add_property_editor(name, control); -// return true; -// } -// else if (hint_string == "VCAAsset") -// { -// InspectorBrowserProperty* control = memnew(InspectorBrowserProperty); -// control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_VCA); -// add_property_editor(name, control); -// return true; -// } -// else if (hint_string == "ParameterAsset") -// { -// InspectorBrowserProperty* control = memnew(InspectorBrowserProperty); -// control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_GLOBAL_PARAMETER); -// add_property_editor(name, control); -// return true; -// } -// -// return false; -// } -// -// return false; -// } -//}; +class FMODEditorInspectorPlugin : public EditorInspectorPlugin +{ + GDCLASS(FMODEditorInspectorPlugin, EditorInspectorPlugin); + +protected: + static void _bind_methods() {} + +private: + float editor_scale = 1.0f; + +public: + virtual bool _can_handle(Object* object) const override + { + return object != nullptr; + } + + virtual bool _parse_property(Object* object, Variant::Type type, const String& name, PropertyHint hint_type, + const String& hint_string, BitField usage_flags, bool wide) override + { + if (object != nullptr && type == Variant::Type::OBJECT) + { + if (hint_string == "EventAsset") + { + FMODEditorInspectorProperty* control = memnew(FMODEditorInspectorProperty); + control->set_editor_scale(editor_scale); + control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_EVENT); + add_property_editor(name, control); + return true; + } + else if (hint_string == "BankAsset") + { + FMODEditorInspectorProperty* control = memnew(FMODEditorInspectorProperty); + control->set_editor_scale(editor_scale); + control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_BANK); + add_property_editor(name, control); + return true; + } + else if (hint_string == "BusAsset") + { + FMODEditorInspectorProperty* control = memnew(FMODEditorInspectorProperty); + control->set_editor_scale(editor_scale); + control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_BUS); + add_property_editor(name, control); + return true; + } + else if (hint_string == "VCAAsset") + { + FMODEditorInspectorProperty* control = memnew(FMODEditorInspectorProperty); + control->set_editor_scale(editor_scale); + control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_VCA); + add_property_editor(name, control); + return true; + } + else if (hint_string == "ParameterAsset") + { + FMODEditorInspectorProperty* control = memnew(FMODEditorInspectorProperty); + control->set_editor_scale(editor_scale); + control->init(FMODStudioEditorModule::FMODAssetType::FMOD_ASSETTYPE_GLOBAL_PARAMETER); + add_property_editor(name, control); + return true; + } + + return false; + } + + return false; + } + + void set_editor_scale(float editor_scale) + { + this->editor_scale = editor_scale; + } +}; #endif // INSPECTOR_BROWSER_H \ No newline at end of file diff --git a/addons/FMOD/native/src/editor/project_browser.cpp b/addons/FMOD/native/src/editor/project_browser.cpp index 4025020..c4bba27 100644 --- a/addons/FMOD/native/src/editor/project_browser.cpp +++ b/addons/FMOD/native/src/editor/project_browser.cpp @@ -4,14 +4,14 @@ using namespace godot; const Size2i BASE_WINDOW_SIZE = Size2i(750, 550); const int BASE_DPI = 96; -const int STANDARD_MARGIN = 20; +const int STANDARD_MARGIN = 10; -void ProjectBrowserTree::_bind_methods() +void FMODProjectBrowserTree::_bind_methods() { - ClassDB::bind_method(D_METHOD("on_connection_finished"), &ProjectBrowserTree::on_connection_finished); + ClassDB::bind_method(D_METHOD("on_connection_finished"), &FMODProjectBrowserTree::on_connection_finished); } -void ProjectBrowserTree::initialize() +void FMODProjectBrowserTree::initialize() { set_allow_reselect(true); set_allow_rmb_select(true); @@ -21,7 +21,7 @@ void ProjectBrowserTree::initialize() populate_browser(); } -void ProjectBrowserTree::populate_browser() +void FMODProjectBrowserTree::populate_browser() { clear(); root = create_item(); @@ -84,7 +84,7 @@ void ProjectBrowserTree::populate_browser() } } -void ProjectBrowserTree::update_project_text() +void FMODProjectBrowserTree::update_project_text() { String project_message = "studio.project.filePath.replace(/^.*[\\\\\\/]/, '')"; String result; @@ -95,7 +95,7 @@ void ProjectBrowserTree::update_project_text() } } -void ProjectBrowserTree::on_connection_finished() +void FMODProjectBrowserTree::on_connection_finished() { if (client->client_is_connected) { @@ -103,12 +103,12 @@ void ProjectBrowserTree::on_connection_finished() } } -void DiscreteParameterControl::_bind_methods() +void FMODEditorDiscreteParameter::_bind_methods() { - ClassDB::bind_method(D_METHOD("on_value_changed", "value"), &DiscreteParameterControl::on_value_changed); + ClassDB::bind_method(D_METHOD("on_value_changed", "value"), &FMODEditorDiscreteParameter::on_value_changed); } -void DiscreteParameterControl::initialize(const Ref& desc, Size2 size) +void FMODEditorDiscreteParameter::initialize(const Ref& desc, Size2 size) { set_min(desc->get_minimum()); set_max(desc->get_maximum()); @@ -124,17 +124,17 @@ void DiscreteParameterControl::initialize(const Refset_preview_parameter(parameter_name, value); } -void LabeledParameterControl::_bind_methods() +void FMODEditorLabeledParameter::_bind_methods() { - ClassDB::bind_method(D_METHOD("on_item_selected", "value"), &LabeledParameterControl::on_item_selected); + ClassDB::bind_method(D_METHOD("on_item_selected", "value"), &FMODEditorLabeledParameter::on_item_selected); } -void LabeledParameterControl::initialize(const Ref& parameter, Size2 size) +void FMODEditorLabeledParameter::initialize(const Ref& parameter, Size2 size) { set_h_size_flags(Control::SizeFlags::SIZE_EXPAND_FILL); set_v_size_flags(Control::SizeFlags::SIZE_SHRINK_CENTER); @@ -150,17 +150,17 @@ void LabeledParameterControl::initialize(const Ref& parameter, S connect("item_selected", Callable(this, "on_item_selected")); } -void LabeledParameterControl::on_item_selected(int value) +void FMODEditorLabeledParameter::on_item_selected(int value) { FMODStudioEditorModule::get_singleton()->set_preview_parameter(parameter_name, static_cast(value)); } -void ContinuousParameterControl::_bind_methods() +void FMODEditorContinuousParameter::_bind_methods() { - ClassDB::bind_method(D_METHOD("on_value_changed", "value"), &ContinuousParameterControl::on_value_changed); + ClassDB::bind_method(D_METHOD("on_value_changed", "value"), &FMODEditorContinuousParameter::on_value_changed); } -void ContinuousParameterControl::initialize(const Ref& desc, Size2 size) +void FMODEditorContinuousParameter::initialize(const Ref& desc, Size2 size) { set_min(desc->get_minimum()); set_max(desc->get_maximum()); @@ -174,43 +174,43 @@ void ContinuousParameterControl::initialize(const Refset_preview_parameter(parameter_name, value); } -void ProjectBrowserWindow::_bind_methods() +void FMODProjectBrowserWindow::_bind_methods() { - ClassDB::bind_method(D_METHOD("on_about_to_popup"), &ProjectBrowserWindow::on_about_to_popup); - ClassDB::bind_method(D_METHOD("on_close_requested"), &ProjectBrowserWindow::on_close_requested); - ClassDB::bind_method(D_METHOD("on_size_changed"), &ProjectBrowserWindow::on_size_changed); - ClassDB::bind_method(D_METHOD("on_github_link_pressed"), &ProjectBrowserWindow::on_github_link_pressed); - ClassDB::bind_method(D_METHOD("on_tutorials_link_pressed"), &ProjectBrowserWindow::on_tutorials_link_pressed); - ClassDB::bind_method(D_METHOD("on_contact_link_pressed"), &ProjectBrowserWindow::on_contact_link_pressed); - ClassDB::bind_method(D_METHOD("on_search_text_changed", "text"), &ProjectBrowserWindow::on_search_text_changed); - ClassDB::bind_method(D_METHOD("on_cell_selected"), &ProjectBrowserWindow::on_cell_selected); - ClassDB::bind_method(D_METHOD("on_refresh_button_pressed"), &ProjectBrowserWindow::on_refresh_button_pressed); + ClassDB::bind_method(D_METHOD("on_about_to_popup"), &FMODProjectBrowserWindow::on_about_to_popup); + ClassDB::bind_method(D_METHOD("on_close_requested"), &FMODProjectBrowserWindow::on_close_requested); + ClassDB::bind_method(D_METHOD("on_size_changed"), &FMODProjectBrowserWindow::on_size_changed); + ClassDB::bind_method(D_METHOD("on_github_link_pressed"), &FMODProjectBrowserWindow::on_github_link_pressed); + ClassDB::bind_method(D_METHOD("on_tutorials_link_pressed"), &FMODProjectBrowserWindow::on_tutorials_link_pressed); + ClassDB::bind_method(D_METHOD("on_contact_link_pressed"), &FMODProjectBrowserWindow::on_contact_link_pressed); + ClassDB::bind_method(D_METHOD("on_search_text_changed", "text"), &FMODProjectBrowserWindow::on_search_text_changed); + ClassDB::bind_method(D_METHOD("on_cell_selected"), &FMODProjectBrowserWindow::on_cell_selected); + ClassDB::bind_method(D_METHOD("on_refresh_button_pressed"), &FMODProjectBrowserWindow::on_refresh_button_pressed); ClassDB::bind_method(D_METHOD("on_generate_guids_button_pressed"), - &ProjectBrowserWindow::on_generate_guids_button_pressed); - ClassDB::bind_method(D_METHOD("on_play_button_pressed"), &ProjectBrowserWindow::on_play_button_pressed); - ClassDB::bind_method(D_METHOD("on_stop_button_pressed"), &ProjectBrowserWindow::on_stop_button_pressed); - ClassDB::bind_method(D_METHOD("on_checkbox_toggled", "button_pressed"), &ProjectBrowserWindow::on_checkbox_toggled); - ClassDB::bind_method(D_METHOD("on_event_popup_id_pressed", "id"), &ProjectBrowserWindow::on_event_popup_id_pressed); - ClassDB::bind_method(D_METHOD("on_bank_popup_id_pressed", "id"), &ProjectBrowserWindow::on_bank_popup_id_pressed); - ClassDB::bind_method(D_METHOD("set_editor_scale", "scale"), &ProjectBrowserWindow::set_editor_scale); - ClassDB::bind_method(D_METHOD("initialize"), &ProjectBrowserWindow::initialize); + &FMODProjectBrowserWindow::on_generate_guids_button_pressed); + ClassDB::bind_method(D_METHOD("on_play_button_pressed"), &FMODProjectBrowserWindow::on_play_button_pressed); + ClassDB::bind_method(D_METHOD("on_stop_button_pressed"), &FMODProjectBrowserWindow::on_stop_button_pressed); + ClassDB::bind_method(D_METHOD("on_checkbox_toggled", "button_pressed"), &FMODProjectBrowserWindow::on_checkbox_toggled); + ClassDB::bind_method(D_METHOD("on_event_popup_id_pressed", "id"), &FMODProjectBrowserWindow::on_event_popup_id_pressed); + ClassDB::bind_method(D_METHOD("on_bank_popup_id_pressed", "id"), &FMODProjectBrowserWindow::on_bank_popup_id_pressed); + ClassDB::bind_method(D_METHOD("set_editor_scale", "scale"), &FMODProjectBrowserWindow::set_editor_scale); + ClassDB::bind_method(D_METHOD("initialize"), &FMODProjectBrowserWindow::initialize); } -void ProjectBrowserWindow::popup_menu(PopupType type, Vector2 pos) +void FMODProjectBrowserWindow::popup_menu(PopupType type, Vector2 pos) { switch (type) { - case ProjectBrowserWindow::POPUP_EVENT: + case FMODProjectBrowserWindow::POPUP_EVENT: { event_popup->popup_on_parent(Rect2(pos, Vector2(0, 0))); break; } - case ProjectBrowserWindow::POPUP_BANK: + case FMODProjectBrowserWindow::POPUP_BANK: bank_popup->popup_on_parent(Rect2(pos, Vector2(0, 0))); break; default: @@ -218,7 +218,7 @@ void ProjectBrowserWindow::popup_menu(PopupType type, Vector2 pos) } } -bool ProjectBrowserWindow::update_filter(TreeItem* p_parent, bool p_scroll_to_selected) +bool FMODProjectBrowserWindow::update_filter(TreeItem* p_parent, bool p_scroll_to_selected) { if (!p_parent) { @@ -276,7 +276,7 @@ bool ProjectBrowserWindow::update_filter(TreeItem* p_parent, bool p_scroll_to_se return keep; } -void ProjectBrowserWindow::collapse_all(TreeItem* p_parent) +void FMODProjectBrowserWindow::collapse_all(TreeItem* p_parent) { if (!p_parent) { @@ -292,7 +292,7 @@ void ProjectBrowserWindow::collapse_all(TreeItem* p_parent) } } -void ProjectBrowserWindow::on_about_to_popup() +void FMODProjectBrowserWindow::on_about_to_popup() { Ref client = FMODStudioEditorModule::get_singleton()->client; @@ -309,40 +309,40 @@ void ProjectBrowserWindow::on_about_to_popup() project_tree->populate_browser(); } -void ProjectBrowserWindow::on_close_requested() +void FMODProjectBrowserWindow::on_close_requested() { set_visible(false); FMODStudioEditorModule::get_singleton()->unload_all_banks(); FMODStudioEditorModule::get_singleton()->shutdown(); } -void ProjectBrowserWindow::on_size_changed() +void FMODProjectBrowserWindow::on_size_changed() { parent_vbox_container->set_size(get_size()); } -void ProjectBrowserWindow::on_github_link_pressed() +void FMODProjectBrowserWindow::on_github_link_pressed() { OS::get_singleton()->shell_open(github_url); } -void ProjectBrowserWindow::on_tutorials_link_pressed() +void FMODProjectBrowserWindow::on_tutorials_link_pressed() { OS::get_singleton()->shell_open(tutorials_url); } -void ProjectBrowserWindow::on_contact_link_pressed() +void FMODProjectBrowserWindow::on_contact_link_pressed() { OS::get_singleton()->shell_open(email_url); } -void ProjectBrowserWindow::on_search_text_changed(const String& text) +void FMODProjectBrowserWindow::on_search_text_changed(const String& text) { filter = text; update_filter(project_tree->root); } -void ProjectBrowserWindow::on_cell_selected() +void FMODProjectBrowserWindow::on_cell_selected() { parameters_margin_container->set_visible(false); @@ -422,7 +422,7 @@ void ProjectBrowserWindow::on_cell_selected() if ((flags & FMOD_STUDIO_PARAMETER_DISCRETE) && !(flags & FMOD_STUDIO_PARAMETER_LABELED)) { - DiscreteParameterControl* spinbox = memnew(DiscreteParameterControl); + FMODEditorDiscreteParameter* spinbox = memnew(FMODEditorDiscreteParameter); spinbox->initialize(parameter_description, Size2(get_size().x / 5, 0)); parameter_hbox_container->add_child(spinbox); @@ -430,7 +430,7 @@ void ProjectBrowserWindow::on_cell_selected() } else if (flags & FMOD_STUDIO_PARAMETER_LABELED) { - LabeledParameterControl* option_button = memnew(LabeledParameterControl); + FMODEditorLabeledParameter* option_button = memnew(FMODEditorLabeledParameter); option_button->initialize(parameter, Size2(get_size().x / 5, 0)); parameter_hbox_container->add_child(option_button); @@ -438,7 +438,7 @@ void ProjectBrowserWindow::on_cell_selected() } else { - ContinuousParameterControl* spin_slider = memnew(ContinuousParameterControl); + FMODEditorContinuousParameter* spin_slider = memnew(FMODEditorContinuousParameter); spin_slider->initialize(parameter_description, Size2(get_size().x / 5, 0)); parameter_hbox_container->add_child(spin_slider); @@ -447,7 +447,7 @@ void ProjectBrowserWindow::on_cell_selected() } } -void ProjectBrowserWindow::on_refresh_button_pressed() +void FMODProjectBrowserWindow::on_refresh_button_pressed() { FMODStudioEditorModule::get_singleton()->unload_all_banks(); FMODStudioEditorModule::get_singleton()->load_all_banks(); @@ -457,7 +457,7 @@ void ProjectBrowserWindow::on_refresh_button_pressed() project_tree->populate_browser(); } -void ProjectBrowserWindow::on_generate_guids_button_pressed() +void FMODProjectBrowserWindow::on_generate_guids_button_pressed() { Ref client = FMODStudioEditorModule::get_singleton()->client; @@ -495,7 +495,7 @@ void ProjectBrowserWindow::on_generate_guids_button_pressed() } } -void ProjectBrowserWindow::on_play_button_pressed() +void FMODProjectBrowserWindow::on_play_button_pressed() { if (!selected_item) { @@ -515,17 +515,17 @@ void ProjectBrowserWindow::on_play_button_pressed() } } -void ProjectBrowserWindow::on_stop_button_pressed() +void FMODProjectBrowserWindow::on_stop_button_pressed() { FMODStudioEditorModule::get_singleton()->stop_events(allow_fadeout); } -void ProjectBrowserWindow::on_checkbox_toggled(bool button_pressed) +void FMODProjectBrowserWindow::on_checkbox_toggled(bool button_pressed) { allow_fadeout = button_pressed; } -void ProjectBrowserWindow::on_event_popup_id_pressed(int32_t id) +void FMODProjectBrowserWindow::on_event_popup_id_pressed(int32_t id) { if (!selected_item) { @@ -574,7 +574,7 @@ void ProjectBrowserWindow::on_event_popup_id_pressed(int32_t id) } } -void ProjectBrowserWindow::on_bank_popup_id_pressed(int32_t id) +void FMODProjectBrowserWindow::on_bank_popup_id_pressed(int32_t id) { if (!selected_item) { @@ -620,7 +620,7 @@ void ProjectBrowserWindow::on_bank_popup_id_pressed(int32_t id) } } -void ProjectBrowserWindow::_input(const Ref& event) +void FMODProjectBrowserWindow::_input(const Ref& event) { if (is_visible()) { @@ -655,21 +655,21 @@ void ProjectBrowserWindow::_input(const Ref& event) } } -void ProjectBrowserWindow::set_editor_scale(float scale) +void FMODProjectBrowserWindow::set_editor_scale(float scale) { editor_scale = scale; } -void ProjectBrowserWindow::initialize() +void FMODProjectBrowserWindow::initialize() { set_initial_position(Window::WindowInitialPosition::WINDOW_INITIAL_POSITION_CENTER_MAIN_WINDOW_SCREEN); set_visible(false); set_wrap_controls(true); set_title("FMOD Project Browser"); set_exclusive(true); - set_transparent_background(true); connect("about_to_popup", Callable(this, "on_about_to_popup")); connect("close_requested", Callable(this, "on_close_requested")); + connect("confirmed", Callable(this, "on_close_requested")); connect("size_changed", Callable(this, "on_size_changed")); Size2 window_size = BASE_WINDOW_SIZE; @@ -688,14 +688,6 @@ void ProjectBrowserWindow::initialize() window_size *= editor_scale; } - // note(alex): The colors of the Window elements (buttons etc.) are almost identical to the background, which make them very hard to distinguish. - // We are adding a Panel here to darken the background of the Window a bit. Investigate what is going wrong here. - panel = memnew(Panel); - panel->set_anchors_preset(Control::LayoutPreset::PRESET_FULL_RECT); - panel->set_self_modulate(Color(1.f, 1.f, 1.f, 0.85f)); - add_child(panel); - panel->set_owner(this); - parent_vbox_container = memnew(VBoxContainer); parent_vbox_container->set_size(window_size); parent_vbox_container->set_custom_minimum_size(window_size); @@ -790,7 +782,7 @@ void ProjectBrowserWindow::initialize() tree_margin_container->add_child(tree_hbox_container); tree_hbox_container->set_owner(tree_margin_container); - project_tree = memnew(ProjectBrowserTree); + project_tree = memnew(FMODProjectBrowserTree); project_tree->client = FMODStudioEditorModule::get_singleton()->client; project_tree->initialize(); project_tree->connect("cell_selected", Callable(this, "on_cell_selected")); @@ -844,7 +836,6 @@ void ProjectBrowserWindow::initialize() bottom_margin_container->add_theme_constant_override("margin_left", 15); bottom_margin_container->add_theme_constant_override("margin_right", 15); bottom_margin_container->add_theme_constant_override("margin_top", 15); - bottom_margin_container->add_theme_constant_override("margin_bottom", 15); bottom_hbox_container->add_child(bottom_margin_container); bottom_margin_container->set_owner(bottom_hbox_container); diff --git a/addons/FMOD/native/src/editor/project_browser.h b/addons/FMOD/native/src/editor/project_browser.h index 95c4d53..48613da 100644 --- a/addons/FMOD/native/src/editor/project_browser.h +++ b/addons/FMOD/native/src/editor/project_browser.h @@ -3,6 +3,7 @@ #include "fmod_assets.h" #include "fmod_studio_editor_module.h" +#include #include #include #include @@ -27,30 +28,30 @@ #include #include #include -#include using namespace godot; -class ProjectBrowserPreviewButton : public Button +class FMODProjectBrowserPreviewButton : public Button { - GDCLASS(ProjectBrowserPreviewButton, Button); + GDCLASS(FMODProjectBrowserPreviewButton, Button); protected: static void _bind_methods(){}; public: - ProjectBrowserPreviewButton() + FMODProjectBrowserPreviewButton() = default; + ~FMODProjectBrowserPreviewButton() = default; + + void initialize() { set_text("FMOD"); set_button_icon(FMODStudioEditorModule::get_singleton()->get_icon(FMODStudioEditorModule::FMODIconType::FMOD_ICONTYPE_PROJECT)); } - - ~ProjectBrowserPreviewButton() = default; }; -class ProjectBrowserTree : public Tree +class FMODProjectBrowserTree : public Tree { - GDCLASS(ProjectBrowserTree, Tree); + GDCLASS(FMODProjectBrowserTree, Tree); protected: static void _bind_methods(); @@ -72,9 +73,9 @@ class ProjectBrowserTree : public Tree void on_connection_finished(); }; -class DiscreteParameterControl : public SpinBox +class FMODEditorDiscreteParameter : public SpinBox { - GDCLASS(DiscreteParameterControl, SpinBox); + GDCLASS(FMODEditorDiscreteParameter, SpinBox); protected: static void _bind_methods(); @@ -85,9 +86,9 @@ class DiscreteParameterControl : public SpinBox void on_value_changed(float value); }; -class LabeledParameterControl : public OptionButton +class FMODEditorLabeledParameter : public OptionButton { - GDCLASS(LabeledParameterControl, OptionButton); + GDCLASS(FMODEditorLabeledParameter, OptionButton); protected: static void _bind_methods(); @@ -98,9 +99,9 @@ class LabeledParameterControl : public OptionButton void on_item_selected(int value); }; -class ContinuousParameterControl : public EditorSpinSlider +class FMODEditorContinuousParameter : public EditorSpinSlider { - GDCLASS(ContinuousParameterControl, EditorSpinSlider); + GDCLASS(FMODEditorContinuousParameter, EditorSpinSlider); protected: static void _bind_methods(); @@ -111,9 +112,9 @@ class ContinuousParameterControl : public EditorSpinSlider void on_value_changed(float value); }; -class ProjectBrowserWindow : public Window +class FMODProjectBrowserWindow : public AcceptDialog { - GDCLASS(ProjectBrowserWindow, Window); + GDCLASS(FMODProjectBrowserWindow, AcceptDialog); enum PopupType { @@ -139,7 +140,6 @@ class ProjectBrowserWindow : public Window static void _bind_methods(); private: - Panel* panel = nullptr; VBoxContainer* parent_vbox_container = nullptr; MarginContainer* top_margin_container = nullptr; VBoxContainer* top_vbox_container = nullptr; @@ -155,7 +155,7 @@ class ProjectBrowserWindow : public Window LineEdit* search_text = nullptr; MarginContainer* tree_margin_container = nullptr; HBoxContainer* tree_hbox_container = nullptr; - ProjectBrowserTree* project_tree = nullptr; + FMODProjectBrowserTree* project_tree = nullptr; MarginContainer* parameters_margin_container = nullptr; VBoxContainer* parameters_grid_container = nullptr; MarginContainer* parameters_title_margin_container = nullptr; diff --git a/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.cpp b/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.cpp index 6d5cca0..0c81def 100644 --- a/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.cpp +++ b/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.cpp @@ -62,8 +62,6 @@ void StudioEventEmitter3DGizmoPlugin::_redraw(const Ref& gizm return; } - - bool is_3d = event_asset->get_3d(); if (!is_3d) @@ -71,12 +69,11 @@ void StudioEventEmitter3DGizmoPlugin::_redraw(const Ref& gizm return; } - float r_max{}; + float r_max{}; float r_min{}; float max_distance = event_asset->get_max_distance(); float min_distance = event_asset->get_min_distance(); - if (max_distance > CMP_EPSILON) { r_max = MIN(1 * soft_multiplier, max_distance); diff --git a/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.h b/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.h index 89709ca..768ef5e 100644 --- a/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.h +++ b/addons/FMOD/native/src/editor/studio_event_emitter_3d_gizmo_plugin.h @@ -1,3 +1,6 @@ +#ifndef STUDIO_EVENT_EMITTER_3D_GIZMO_PLUGIN +#define STUDIO_EVENT_EMITTER_3D_GIZMO_PLUGIN + // This is slighty modified version of Godot's AudioStreamPlayer3DGizmoPlugin // in editor/plugins/node_3d_editor_gizmos.cpp and adapted to also display // the minimum distance of an FMOD Event. @@ -31,3 +34,5 @@ class StudioEventEmitter3DGizmoPlugin : public EditorNode3DGizmoPlugin virtual int32_t _get_priority() const override; virtual void _redraw(const Ref& gizmo) override; }; + +#endif \ No newline at end of file diff --git a/addons/FMOD/native/src/fmod_studio_editor_module.cpp b/addons/FMOD/native/src/fmod_studio_editor_module.cpp index 3ed2c63..d97e51c 100644 --- a/addons/FMOD/native/src/fmod_studio_editor_module.cpp +++ b/addons/FMOD/native/src/fmod_studio_editor_module.cpp @@ -3,12 +3,30 @@ using namespace godot; FMODStudioEditorModule* FMODStudioEditorModule::singleton = nullptr; +FMODSettings* FMODSettings::singleton = nullptr; void FMODSettings::_bind_methods() { } FMODSettings::FMODSettings() +{ + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} + +FMODSettings::~FMODSettings() +{ + ERR_FAIL_COND(singleton != this); + singleton = nullptr; +} + +FMODSettings* FMODSettings::get_singleton() +{ + return nullptr; +} + +void FMODSettings::initialize() { add_fmod_settings(); @@ -430,6 +448,8 @@ bool FMODStudioEditorModule::init() return result; } + set_is_initialized(true); + String message = "[FMOD] Initialized Editor System"; UtilityFunctions::print(message); @@ -443,6 +463,7 @@ void FMODStudioEditorModule::shutdown() { if (shutdown_fmod()) { + set_is_initialized(false); String message = "[FMOD] Shut down Editor System"; UtilityFunctions::print(message); } @@ -616,196 +637,199 @@ Dictionary FMODStudioEditorModule::get_project_info_from_banks() Dictionary events, snapshots, busses, vcas, parameters, banks; - for (int64_t i = 0; i < bank_refs.size(); i++) + if (get_is_initialized()) { - Ref bank_asset = bank_refs[i]; - FMOD::Studio::Bank* bank = nullptr; - String guid = bank_asset->get_guid(); - FMOD_GUID fmod_guid{}; - FMOD_Studio_ParseID(guid.utf8().get_data(), &fmod_guid); - - if (!studio_system) + for (int64_t i = 0; i < bank_refs.size(); i++) { - break; - } + Ref bank_asset = bank_refs[i]; + String guid = bank_asset->get_guid(); + FMOD_GUID fmod_guid{}; + FMOD_Studio_ParseID(guid.utf8().get_data(), &fmod_guid); - studio_system->getBankByID(&fmod_guid, &bank); + if (!studio_system) + { + break; + } - if (!FileAccess::file_exists(resource_dirs["banks"].operator godot::String() + guid + ".tres")) - { - ResourceSaver::get_singleton()->save(bank_asset, resource_dirs["banks"].operator godot::String() + guid + ".tres"); - banks[guid] = bank_asset; - } - else - { - Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["banks"].operator godot::String() + guid + ".tres", "BankAsset"); - asset->set_name(bank_asset->get_name()); - asset->set_path(bank_asset->get_path()); - asset->set_modified_time(bank_asset->get_modified_time()); - ResourceSaver::get_singleton()->save(asset, resource_dirs["banks"].operator godot::String() + guid + ".tres"); - banks[guid] = asset; - } + FMOD::Studio::Bank* bank = nullptr; + studio_system->getBankByID(&fmod_guid, &bank); - int event_count = 0; - bank->getEventCount(&event_count); + if (!FileAccess::file_exists(resource_dirs["banks"].operator godot::String() + guid + ".tres")) + { + ResourceSaver::get_singleton()->save(bank_asset, resource_dirs["banks"].operator godot::String() + guid + ".tres"); + banks[guid] = bank_asset; + } + else + { + Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["banks"].operator godot::String() + guid + ".tres", "BankAsset"); + asset->set_name(bank_asset->get_name()); + asset->set_path(bank_asset->get_path()); + asset->set_modified_time(bank_asset->get_modified_time()); + ResourceSaver::get_singleton()->save(asset, resource_dirs["banks"].operator godot::String() + guid + ".tres"); + banks[guid] = asset; + } - if (event_count > 0) - { - Dictionary event_infos = get_event_list(bank, event_count); - Array events_array = event_infos["events"]; - Array snapshots_array = event_infos["snapshots"]; + int event_count = 0; + bank->getEventCount(&event_count); - for (int64_t i = 0; i < events_array.size(); i++) + if (event_count > 0) { - Ref event = events_array[i]; - String guid = event->get_guid(); + Dictionary event_infos = get_event_list(bank, event_count); + Array events_array = event_infos["events"]; + Array snapshots_array = event_infos["snapshots"]; - if (!FileAccess::file_exists(resource_dirs["events"].operator godot::String() + guid + ".tres")) + for (int64_t i = 0; i < events_array.size(); i++) { - ResourceSaver::get_singleton()->save(event, resource_dirs["events"].operator godot::String() + guid + ".tres"); - events[guid] = event; + Ref event = events_array[i]; + String guid = event->get_guid(); + + if (!FileAccess::file_exists(resource_dirs["events"].operator godot::String() + guid + ".tres")) + { + ResourceSaver::get_singleton()->save(event, resource_dirs["events"].operator godot::String() + guid + ".tres"); + events[guid] = event; + } + else + { + Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["events"].operator godot::String() + guid + ".tres", "EventAsset"); + + if (has_event_changed(asset, event)) + { + asset->set_name(event->get_name()); + asset->set_path(event->get_path()); + asset->set_3d(event->get_3d()); + asset->set_oneshot(event->get_oneshot()); + asset->set_is_snapshot(event->get_is_snapshot()); + asset->set_min_distance(event->get_min_distance()); + asset->set_max_distance(event->get_max_distance()); + asset->set_parameters(event->get_parameters()); + ResourceSaver::get_singleton()->save(asset, resource_dirs["events"].operator godot::String() + guid + ".tres"); + } + events[guid] = asset; + } } - else + + for (int64_t i = 0; i < snapshots_array.size(); i++) { - Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["events"].operator godot::String() + guid + ".tres", "EventAsset"); + Ref snapshot = snapshots_array[i]; + String guid = snapshot->get_guid(); - if (has_event_changed(asset, event)) + if (!FileAccess::file_exists(resource_dirs["snapshots"].operator godot::String() + guid + ".tres")) + { + ResourceSaver::get_singleton()->save(snapshot, resource_dirs["snapshots"].operator godot::String() + guid + ".tres"); + snapshots[guid] = ResourceSaver::get_singleton()->save(snapshot, resource_dirs["snapshots"].operator godot::String() + guid + ".tres"); + } + else { - asset->set_name(event->get_name()); - asset->set_path(event->get_path()); - asset->set_3d(event->get_3d()); - asset->set_oneshot(event->get_oneshot()); - asset->set_is_snapshot(event->get_is_snapshot()); - asset->set_min_distance(event->get_min_distance()); - asset->set_max_distance(event->get_max_distance()); - asset->set_parameters(event->get_parameters()); - ResourceSaver::get_singleton()->save(asset, resource_dirs["events"].operator godot::String() + guid + ".tres"); + Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["snapshots"].operator godot::String() + guid + ".tres", "EventAsset"); + if (has_event_changed(asset, snapshot)) + { + asset->set_name(snapshot->get_name()); + asset->set_path(snapshot->get_path()); + asset->set_3d(snapshot->get_3d()); + asset->set_oneshot(snapshot->get_oneshot()); + asset->set_is_snapshot(snapshot->get_is_snapshot()); + asset->set_min_distance(snapshot->get_min_distance()); + asset->set_max_distance(snapshot->get_max_distance()); + asset->set_parameters(snapshot->get_parameters()); + ResourceSaver::get_singleton()->save(asset, resource_dirs["snapshots"].operator godot::String() + guid + ".tres"); + } + snapshots[guid] = asset; } - events[guid] = asset; } } - for (int64_t i = 0; i < snapshots_array.size(); i++) + int bus_count = 0; + bank->getBusCount(&bus_count); + + if (bus_count > 0) { - Ref snapshot = snapshots_array[i]; - String guid = snapshot->get_guid(); + Array bus_infos = get_bus_list(bank, bus_count); - if (!FileAccess::file_exists(resource_dirs["snapshots"].operator godot::String() + guid + ".tres")) + for (int64_t i = 0; i < bus_infos.size(); i++) { - ResourceSaver::get_singleton()->save(snapshot, resource_dirs["snapshots"].operator godot::String() + guid + ".tres"); - snapshots[guid] = ResourceSaver::get_singleton()->save(snapshot, resource_dirs["snapshots"].operator godot::String() + guid + ".tres"); - } - else - { - Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["snapshots"].operator godot::String() + guid + ".tres", "EventAsset"); - if (has_event_changed(asset, snapshot)) + Ref bus = bus_infos[i]; + String guid = bus->get_guid(); + + if (!FileAccess::file_exists(resource_dirs["busses"].operator godot::String() + guid + ".tres")) + { + ResourceSaver::get_singleton()->save(bus, resource_dirs["busses"].operator godot::String() + guid + ".tres"); + busses[guid] = bus; + } + else { - asset->set_name(snapshot->get_name()); - asset->set_path(snapshot->get_path()); - asset->set_3d(snapshot->get_3d()); - asset->set_oneshot(snapshot->get_oneshot()); - asset->set_is_snapshot(snapshot->get_is_snapshot()); - asset->set_min_distance(snapshot->get_min_distance()); - asset->set_max_distance(snapshot->get_max_distance()); - asset->set_parameters(snapshot->get_parameters()); - ResourceSaver::get_singleton()->save(asset, resource_dirs["snapshots"].operator godot::String() + guid + ".tres"); + Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["busses"].operator godot::String() + guid + ".tres", "BusAsset"); + asset->set_name(bus->get_name()); + asset->set_path(bus->get_path()); + ResourceSaver::get_singleton()->save(asset, resource_dirs["busses"].operator godot::String() + guid + ".tres"); + busses[guid] = asset; } - snapshots[guid] = asset; } } - } - - int bus_count = 0; - bank->getBusCount(&bus_count); - if (bus_count > 0) - { - Array bus_infos = get_bus_list(bank, bus_count); + int vca_count = 0; + bank->getVCACount(&vca_count); - for (int64_t i = 0; i < bus_infos.size(); i++) + if (vca_count > 0) { - Ref bus = bus_infos[i]; - String guid = bus->get_guid(); - - if (!FileAccess::file_exists(resource_dirs["busses"].operator godot::String() + guid + ".tres")) + Array vca_infos = get_vca_list(bank, vca_count); + for (int64_t i = 0; i < vca_infos.size(); i++) { - ResourceSaver::get_singleton()->save(bus, resource_dirs["busses"].operator godot::String() + guid + ".tres"); - busses[guid] = bus; - } - else - { - Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["busses"].operator godot::String() + guid + ".tres", "BusAsset"); - asset->set_name(bus->get_name()); - asset->set_path(bus->get_path()); - ResourceSaver::get_singleton()->save(asset, resource_dirs["busses"].operator godot::String() + guid + ".tres"); - busses[guid] = asset; + Ref vca = vca_infos[i]; + String guid = vca->get_guid(); + + if (!FileAccess::file_exists(resource_dirs["vcas"].operator godot::String() + guid + ".tres")) + { + ResourceSaver::get_singleton()->save(vca, resource_dirs["vcas"].operator godot::String() + guid + ".tres"); + vcas[guid] = vca; + } + else + { + Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["vcas"].operator godot::String() + guid + ".tres", "VCAAsset"); + asset->set_name(vca->get_name()); + asset->set_path(vca->get_path()); + ResourceSaver::get_singleton()->save(asset, resource_dirs["vcas"].operator godot::String() + guid + ".tres"); + vcas[guid] = asset; + } } } } - int vca_count = 0; - bank->getVCACount(&vca_count); + int parameter_count = 0; + + if (studio_system) + { + studio_system->getParameterDescriptionCount(¶meter_count); + } - if (vca_count > 0) + if (parameter_count > 0) { - Array vca_infos = get_vca_list(bank, vca_count); - for (int64_t i = 0; i < vca_infos.size(); i++) + Array parameter_infos = get_global_parameter_list(parameter_count); + for (int64_t i = 0; i < parameter_infos.size(); i++) { - Ref vca = vca_infos[i]; - String guid = vca->get_guid(); + Ref parameter = parameter_infos[i]; + String guid = parameter->get_guid(); - if (!FileAccess::file_exists(resource_dirs["vcas"].operator godot::String() + guid + ".tres")) + if (!FileAccess::file_exists(resource_dirs["parameters"].operator godot::String() + guid + ".tres")) { - ResourceSaver::get_singleton()->save(vca, resource_dirs["vcas"].operator godot::String() + guid + ".tres"); - vcas[guid] = vca; + ResourceSaver::get_singleton()->save(parameter, resource_dirs["parameters"].operator godot::String() + guid + ".tres"); + parameters[guid] = parameter; } else { - Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["vcas"].operator godot::String() + guid + ".tres", "VCAAsset"); - asset->set_name(vca->get_name()); - asset->set_path(vca->get_path()); - ResourceSaver::get_singleton()->save(asset, resource_dirs["vcas"].operator godot::String() + guid + ".tres"); - vcas[guid] = asset; + Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["parameters"].operator godot::String() + guid + ".tres", "ParameterAsset"); + asset->set_name(parameter->get_name()); + asset->set_path(parameter->get_path()); + asset->set_parameter_description(parameter->get_parameter_description()); + FMOD_STUDIO_PARAMETER_DESCRIPTION desc; + parameter->get_parameter_description()->get_parameter_description(desc); + asset->set_parameter_ref(desc); + ResourceSaver::get_singleton()->save(asset, resource_dirs["parameters"].operator godot::String() + guid + ".tres"); + parameters[guid] = asset; } } } } - int parameter_count = 0; - - if (studio_system) - { - studio_system->getParameterDescriptionCount(¶meter_count); - } - - if (parameter_count > 0) - { - Array parameter_infos = get_global_parameter_list(parameter_count); - for (int64_t i = 0; i < parameter_infos.size(); i++) - { - Ref parameter = parameter_infos[i]; - String guid = parameter->get_guid(); - - if (!FileAccess::file_exists(resource_dirs["parameters"].operator godot::String() + guid + ".tres")) - { - ResourceSaver::get_singleton()->save(parameter, resource_dirs["parameters"].operator godot::String() + guid + ".tres"); - parameters[guid] = parameter; - } - else - { - Ref asset = ResourceLoader::get_singleton()->load(resource_dirs["parameters"].operator godot::String() + guid + ".tres", "ParameterAsset"); - asset->set_name(parameter->get_name()); - asset->set_path(parameter->get_path()); - asset->set_parameter_description(parameter->get_parameter_description()); - FMOD_STUDIO_PARAMETER_DESCRIPTION desc; - parameter->get_parameter_description()->get_parameter_description(desc); - asset->set_parameter_ref(desc); - ResourceSaver::get_singleton()->save(asset, resource_dirs["parameters"].operator godot::String() + guid + ".tres"); - parameters[guid] = asset; - } - } - } - Dictionary result; result["events"] = events; result["snapshots"] = snapshots; @@ -1074,12 +1098,14 @@ bool FMODStudioEditorModule::sort_parameters_by_name(const Variant& a, const Var bool FMODStudioEditorModule::has_event_changed(const Ref& old_event, const Ref& to_check) { String old_name = old_event->get_name(); + String old_path = old_event->get_path(); bool old_3d = old_event->get_3d(); bool old_oneshot = old_event->get_oneshot(); float old_max_distance = old_event->get_max_distance(); float old_min_distance = old_event->get_min_distance(); if (old_name != to_check->get_name() || + old_path != to_check->get_path() || old_3d != to_check->get_3d() || old_oneshot != to_check->get_oneshot() || old_max_distance != to_check->get_max_distance() || @@ -1149,7 +1175,7 @@ void FMODStudioEditorModule::stop_events(bool allow_fadeout) void FMODStudioEditorModule::set_preview_parameter(const String& parameter_name, float value) { - // note(alex): make this better in the future + // note(alex): make this better in the future - Doesn't work for one shots for example for (int i = 0; i < preview_events.size(); i++) { preview_events[i]->setParameterByName(parameter_name.utf8().get_data(), value); diff --git a/addons/FMOD/native/src/fmod_studio_editor_module.h b/addons/FMOD/native/src/fmod_studio_editor_module.h index 1a25234..fadfada 100644 --- a/addons/FMOD/native/src/fmod_studio_editor_module.h +++ b/addons/FMOD/native/src/fmod_studio_editor_module.h @@ -33,10 +33,14 @@ class FMODSettings : public RefCounted GDCLASS(FMODSettings, RefCounted); protected: + static FMODSettings* singleton; static void _bind_methods(); public: FMODSettings(); + ~FMODSettings(); + static FMODSettings* get_singleton(); + void initialize(); private: void add_fmod_settings(); diff --git a/addons/FMOD/native/src/misc/fmod_io.h b/addons/FMOD/native/src/misc/fmod_io.h index 9520d45..2cd0429 100644 --- a/addons/FMOD/native/src/misc/fmod_io.h +++ b/addons/FMOD/native/src/misc/fmod_io.h @@ -27,7 +27,6 @@ class FMODGodotBlockingIO if (FileAccess::get_open_error() != Error::OK) { *filesize = 0; - file->close(); memfree(file_handle); return FMOD_ERR_FILE_NOTFOUND; } diff --git a/addons/FMOD/native/src/register_types.cpp b/addons/FMOD/native/src/register_types.cpp index 02ce662..b04b550 100644 --- a/addons/FMOD/native/src/register_types.cpp +++ b/addons/FMOD/native/src/register_types.cpp @@ -21,18 +21,21 @@ void register_fmod_types(ModuleInitializationLevel p_level) // Editor Utilities ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - // ClassDB::register_class(); - - ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); - - ClassDB::register_class(); - ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + + ClassDB::register_class(); + ClassDB::register_class(); + + ClassDB::register_class(); + EditorPlugins::add_by_type(); } if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) @@ -96,6 +99,7 @@ void unregister_fmod_types(ModuleInitializationLevel p_level) { Engine::get_singleton()->unregister_singleton("FMODStudioEditorModule"); memdelete(fmod_editor_module); + EditorPlugins::remove_by_type(); } if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) diff --git a/addons/FMOD/native/src/register_types.h b/addons/FMOD/native/src/register_types.h index 46dec1d..e5f6a00 100644 --- a/addons/FMOD/native/src/register_types.h +++ b/addons/FMOD/native/src/register_types.h @@ -8,6 +8,7 @@ #include #include "api/studio_api.h" +#include "editor/fmod_plugin.h" #include "editor/inspector_browser.h" #include "editor/project_browser.h" #include "editor/studio_event_emitter_3d_gizmo_plugin.h" diff --git a/addons/FMOD/runtime/runtime_manager.gd b/addons/FMOD/runtime/fmod_runtime_manager.gd similarity index 95% rename from addons/FMOD/runtime/runtime_manager.gd rename to addons/FMOD/runtime/fmod_runtime_manager.gd index 0c25cc7..03c3746 100644 --- a/addons/FMOD/runtime/runtime_manager.gd +++ b/addons/FMOD/runtime/fmod_runtime_manager.gd @@ -30,12 +30,12 @@ func _notification(what: int) -> void: func path_to_guid(path: String) -> String: - return RuntimeManager.studio_system.lookup_id(path) + return FMODRuntime.studio_system.lookup_id(path) func get_event_description(event_asset: EventAsset) -> EventDescription: var description: EventDescription - description = RuntimeManager.studio_system.get_event_by_id(event_asset.guid) + description = FMODRuntime.studio_system.get_event_by_id(event_asset.guid) return description @@ -47,7 +47,7 @@ func get_event_description_path(event_path: String) -> EventDescription: func get_event_description_id(guid: String) -> EventDescription: var description: EventDescription - description = RuntimeManager.studio_system.get_event_by_id(guid) + description = FMODRuntime.studio_system.get_event_by_id(guid) return description @@ -124,7 +124,7 @@ func play_one_shot_id(guid: String, position = null) -> void: func attach_instance_to_node(instance: EventInstance, node, physicsbody = null) -> void: - var runtime_manager = RuntimeManager + var runtime_manager = FMODRuntime var attached_instance: AttachedInstance for i in runtime_manager.attached_instances.size(): if runtime_manager.attached_instances[i].instance == instance: @@ -141,7 +141,7 @@ func attach_instance_to_node(instance: EventInstance, node, physicsbody = null) func detach_instance_from_node(instance: EventInstance) -> void: - var runtime_manager = RuntimeManager + var runtime_manager = FMODRuntime for i in runtime_manager.attached_instances.size(): if runtime_manager.attached_instances[i].instance == instance: runtime_manager.attached_instances[i] = runtime_manager.attached_instances[ @@ -187,4 +187,4 @@ func _process(_delta: float) -> void: "[FMOD] Trying to set FMOD_3D_ATTRIBUTES for an attached instance, but the instance is not inside the scene tree anymore. Detach the instance before removing the node from the tree." ) i = i + 1 - studio_system.update() \ No newline at end of file + studio_system.update() diff --git a/addons/FMOD/tests/fmod_test_framework.gd b/addons/FMOD/tests/fmod_test_framework.gd index 6885e00..5cc9db7 100644 --- a/addons/FMOD/tests/fmod_test_framework.gd +++ b/addons/FMOD/tests/fmod_test_framework.gd @@ -74,7 +74,7 @@ func run_tests(tests, randomize) -> Dictionary: if randomize: tests.shuffle() for test in tests: - RuntimeManager.studio_system.update() + FMODRuntime.studio_system.update() if test["func"].call(): passed += 1 print_rich("[color=green]PASS: ", test["name"] + "[/color]") diff --git a/addons/FMOD/tests/test_studiosystem.gd b/addons/FMOD/tests/test_studiosystem.gd index 93a7da7..96f625a 100644 --- a/addons/FMOD/tests/test_studiosystem.gd +++ b/addons/FMOD/tests/test_studiosystem.gd @@ -65,7 +65,7 @@ func test_get_bank() -> bool: func test_get_event_by_id() -> bool: - var guid = RuntimeManager.path_to_guid("event:/TestEvent") + var guid = FMODRuntime.path_to_guid("event:/TestEvent") var result_1 = FMODStudioModule.get_studio_system().get_event_by_id(guid) var result_2 = fmod_assert(result_1 is EventDescription) if result_1 and result_2: @@ -76,7 +76,7 @@ func test_get_event_by_id() -> bool: func test_get_bus_by_id() -> bool: - var guid = RuntimeManager.path_to_guid("bus:/TestBus") + var guid = FMODRuntime.path_to_guid("bus:/TestBus") var result_1 = FMODStudioModule.get_studio_system().get_bus_by_id(guid) var result_2 = fmod_assert(result_1 is Bus) if result_1 and result_2: @@ -87,7 +87,7 @@ func test_get_bus_by_id() -> bool: func test_get_vca_by_id() -> bool: - var guid = RuntimeManager.path_to_guid("vca:/TestVCA") + var guid = FMODRuntime.path_to_guid("vca:/TestVCA") var result_1 = FMODStudioModule.get_studio_system().get_vca_by_id(guid) var result_2 = fmod_assert(result_1 is VCA) if result_1 and result_2: @@ -98,7 +98,7 @@ func test_get_vca_by_id() -> bool: func test_get_bank_by_id() -> bool: - var guid = RuntimeManager.path_to_guid("bank:/Master") + var guid = FMODRuntime.path_to_guid("bank:/Master") var result_1 = FMODStudioModule.get_studio_system().get_bank_by_id(guid) var result_2 = fmod_assert(result_1 is Bank) if result_1 and result_2: