Merge pull request #81374 from akien-mga/3.5-cherrypicks
Cherry-picks for the 3.5 branch (future 3.5.3) - 3rd batch
This commit is contained in:
commit
fc32e066af
|
@ -1,5 +1,6 @@
|
|||
name: 🤖 Android Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
@ -17,7 +18,7 @@ jobs:
|
|||
name: Template (target=release, tools=no)
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Azure repositories are not reliable, we need to prevent azure giving us packages.
|
||||
- name: Make apt sources.list use the default Ubuntu repositories
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: 🍏 iOS Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
@ -17,7 +18,7 @@ jobs:
|
|||
name: Template (target=release, tools=no)
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Godot build cache
|
||||
uses: ./.github/actions/godot-cache
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: 🌐 JavaScript Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
@ -19,7 +20,7 @@ jobs:
|
|||
name: Template (target=release, tools=no)
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Emscripten latest
|
||||
uses: mymindstorm/setup-emsdk@v12
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: 🐧 Linux Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
@ -48,7 +49,7 @@ jobs:
|
|||
artifact: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Linux dependencies
|
||||
shell: bash
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: 🍎 macOS Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
@ -31,7 +32,7 @@ jobs:
|
|||
tools: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Godot build cache
|
||||
uses: ./.github/actions/godot-cache
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
name: 🔗 GHA
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-runner
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
static-checks:
|
||||
name: 📊 Static
|
||||
uses: ./.github/workflows/static_checks.yml
|
||||
|
||||
android-build:
|
||||
name: 🤖 Android
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/android_builds.yml
|
||||
|
||||
ios-build:
|
||||
name: 🍏 iOS
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/ios_builds.yml
|
||||
|
||||
javascript-build:
|
||||
name: 🌐 JavaScript
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/javascript_builds.yml
|
||||
|
||||
linux-build:
|
||||
name: 🐧 Linux
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/linux_builds.yml
|
||||
|
||||
macos-build:
|
||||
name: 🍎 macOS
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/macos_builds.yml
|
||||
|
||||
server-build:
|
||||
name: ☁ Server
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/server_builds.yml
|
||||
|
||||
windows-build:
|
||||
name: 🏁 Windows
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/windows_builds.yml
|
|
@ -1,5 +1,6 @@
|
|||
name: ☁ Server Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
|
@ -30,7 +31,7 @@ jobs:
|
|||
tools: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Linux dependencies
|
||||
shell: bash
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: 📊 Static Checks
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
|
||||
|
@ -11,7 +12,7 @@ jobs:
|
|||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Azure repositories are not reliable, we need to prevent Azure giving us packages.
|
||||
- name: Make apt sources.list use the default Ubuntu repositories
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: 🏁 Windows Builds
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
# Global Settings
|
||||
# SCONS_CACHE for windows must be set in the build environment
|
||||
|
@ -34,7 +35,7 @@ jobs:
|
|||
tools: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Godot build cache
|
||||
uses: ./.github/actions/godot-cache
|
||||
|
|
|
@ -131,23 +131,9 @@ cppcheck-cppcheck-build-dir/
|
|||
*.pydevproject
|
||||
*.launch
|
||||
|
||||
# Gcov and Lcov code coverage
|
||||
*.gcno
|
||||
# GCOV code coverage
|
||||
*.gcda
|
||||
*.gcov.html
|
||||
*.func.html
|
||||
*.func-sort-c.html
|
||||
*index-sort-f.html
|
||||
*index-sort-l.html
|
||||
*index.html
|
||||
godot.info
|
||||
amber.png
|
||||
emerald.png
|
||||
glass.png
|
||||
ruby.png
|
||||
snow.png
|
||||
updown.png
|
||||
gcov.css
|
||||
*.gcno
|
||||
|
||||
# Geany
|
||||
*.geany
|
||||
|
@ -246,9 +232,6 @@ xcuserdata/
|
|||
x64/
|
||||
x86/
|
||||
|
||||
# Do not ignore x86 folders anywhere under thirdparty libraries
|
||||
!thirdparty/**/x86/
|
||||
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
|
@ -258,6 +241,12 @@ bld/
|
|||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Do not ignore arch-specific folders anywhere under thirdparty libraries
|
||||
!thirdparty/**/x64/
|
||||
!thirdparty/**/x86/
|
||||
!thirdparty/**/arm/
|
||||
!thirdparty/**/arm64/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ public:
|
|||
template <class T>
|
||||
static void register_class() {
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
ERR_FAIL_COND(!t);
|
||||
|
@ -182,6 +183,7 @@ public:
|
|||
template <class T>
|
||||
static void register_virtual_class() {
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
ERR_FAIL_COND(!t);
|
||||
|
@ -198,6 +200,7 @@ public:
|
|||
template <class T>
|
||||
static void register_custom_instance_class() {
|
||||
GLOBAL_LOCK_FUNCTION;
|
||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||
T::initialize_class();
|
||||
ClassInfo *t = classes.getptr(T::get_class_static());
|
||||
ERR_FAIL_COND(!t);
|
||||
|
|
|
@ -2477,6 +2477,9 @@ void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_s
|
|||
}
|
||||
|
||||
void Image::fill(const Color &p_color) {
|
||||
if (data.size() == 0) {
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
|
||||
|
||||
lock();
|
||||
|
@ -2495,6 +2498,9 @@ void Image::fill(const Color &p_color) {
|
|||
}
|
||||
|
||||
void Image::fill_rect(const Rect2 &p_rect, const Color &p_color) {
|
||||
if (data.size() == 0) {
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats.");
|
||||
|
||||
Rect2i r = Rect2i(0, 0, width, height).clip(p_rect.abs());
|
||||
|
|
|
@ -267,6 +267,7 @@ private:
|
|||
friend class ClassDB; \
|
||||
\
|
||||
public: \
|
||||
typedef m_class self_type; \
|
||||
virtual String get_class() const { \
|
||||
return String(#m_class); \
|
||||
} \
|
||||
|
@ -405,6 +406,8 @@ class ObjectRC;
|
|||
|
||||
class Object {
|
||||
public:
|
||||
typedef Object self_type;
|
||||
|
||||
enum ConnectFlags {
|
||||
|
||||
CONNECT_DEFERRED = 1,
|
||||
|
|
|
@ -1532,7 +1532,7 @@ static String rtos_fix(double p_value) {
|
|||
}
|
||||
}
|
||||
|
||||
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) {
|
||||
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count) {
|
||||
switch (p_variant.get_type()) {
|
||||
case Variant::NIL: {
|
||||
p_store_string_func(p_store_string_ud, "null");
|
||||
|
@ -1649,6 +1649,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
} break;
|
||||
|
||||
case Variant::OBJECT: {
|
||||
if (unlikely(p_recursion_count > MAX_RECURSION)) {
|
||||
ERR_PRINT("Max recursion reached");
|
||||
p_store_string_func(p_store_string_ud, "null");
|
||||
return OK;
|
||||
}
|
||||
p_recursion_count++;
|
||||
|
||||
Object *obj = p_variant;
|
||||
|
||||
if (!obj) {
|
||||
|
@ -1698,7 +1705,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
}
|
||||
|
||||
p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":");
|
||||
write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
|
||||
write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1707,6 +1714,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
} break;
|
||||
|
||||
case Variant::DICTIONARY: {
|
||||
if (unlikely(p_recursion_count > MAX_RECURSION)) {
|
||||
ERR_PRINT("Max recursion reached");
|
||||
p_store_string_func(p_store_string_ud, "{}");
|
||||
return OK;
|
||||
}
|
||||
p_recursion_count++;
|
||||
|
||||
Dictionary dict = p_variant;
|
||||
|
||||
List<Variant> keys;
|
||||
|
@ -1719,9 +1733,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
if (!_check_type(dict[E->get()]))
|
||||
continue;
|
||||
*/
|
||||
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
|
||||
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||
p_store_string_func(p_store_string_ud, ": ");
|
||||
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
|
||||
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||
if (E->next()) {
|
||||
p_store_string_func(p_store_string_ud, ",\n");
|
||||
} else {
|
||||
|
@ -1733,6 +1747,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
|
||||
} break;
|
||||
case Variant::ARRAY: {
|
||||
if (unlikely(p_recursion_count > MAX_RECURSION)) {
|
||||
ERR_PRINT("Max recursion reached");
|
||||
p_store_string_func(p_store_string_ud, "[]");
|
||||
return OK;
|
||||
}
|
||||
p_recursion_count++;
|
||||
|
||||
p_store_string_func(p_store_string_ud, "[ ");
|
||||
Array array = p_variant;
|
||||
int len = array.size();
|
||||
|
@ -1740,7 +1761,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
if (i > 0) {
|
||||
p_store_string_func(p_store_string_ud, ", ");
|
||||
}
|
||||
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
|
||||
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
|
||||
}
|
||||
p_store_string_func(p_store_string_ud, " ]");
|
||||
|
||||
|
@ -1871,6 +1892,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
|||
p_store_string_func(p_store_string_ud, " )");
|
||||
|
||||
} break;
|
||||
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
|
||||
typedef String (*EncodeResourceFunc)(void *ud, const RES &p_resource);
|
||||
|
||||
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud);
|
||||
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0);
|
||||
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
|
||||
};
|
||||
|
||||
|
|
|
@ -787,6 +787,9 @@ def generate_vs_project(env, num_jobs):
|
|||
if env["custom_modules"]:
|
||||
common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
|
||||
|
||||
if env["incremental_link"]:
|
||||
common_build_postfix.append("incremental_link=yes")
|
||||
|
||||
result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
|
||||
return result
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
!/debug
|
|
@ -108,6 +108,12 @@ def configure(env):
|
|||
env.Append(CCFLAGS=["-flto=full"])
|
||||
env.Append(LINKFLAGS=["-flto=full"])
|
||||
|
||||
if env["use_thinlto"] or env["use_lto"]:
|
||||
# Workaround https://github.com/emscripten-core/emscripten/issues/19781.
|
||||
cc_semver = tuple(get_compiler_version(env))
|
||||
if cc_semver >= (3, 1, 42):
|
||||
env.Append(LINKFLAGS=["-Wl,-u,scalbnf"])
|
||||
|
||||
# Sanitizers
|
||||
if env["use_ubsan"]:
|
||||
env.Append(CCFLAGS=["-fsanitize=undefined"])
|
||||
|
|
|
@ -205,7 +205,9 @@ const GodotJSWrapper = {
|
|||
return;
|
||||
}
|
||||
const args = Array.from(arguments);
|
||||
func(p_ref, GodotJSWrapper.get_proxied(args), args.length);
|
||||
const argsProxy = new GodotJSWrapper.MyProxy(args);
|
||||
func(p_ref, argsProxy.get_id(), args.length);
|
||||
argsProxy.unref();
|
||||
};
|
||||
id = GodotJSWrapper.get_proxied(cb);
|
||||
return id;
|
||||
|
|
|
@ -73,6 +73,7 @@ def get_opts():
|
|||
BoolVariable("use_thinlto", "Use ThinLTO", False),
|
||||
BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True),
|
||||
BoolVariable("use_asan", "Use address sanitizer (ASAN)", False),
|
||||
BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False),
|
||||
]
|
||||
|
||||
|
||||
|
@ -216,8 +217,9 @@ def configure_msvc(env, manual_msvc_config):
|
|||
else:
|
||||
env.AppendUnique(CCFLAGS=["/MD"])
|
||||
|
||||
# MSVC incremental linking is broken and _increases_ link time (GH-77968).
|
||||
env.Append(LINKFLAGS=["/INCREMENTAL:NO"])
|
||||
# MSVC incremental linking is broken and may _increase_ link time (GH-77968).
|
||||
if not env["incremental_link"]:
|
||||
env.Append(LINKFLAGS=["/INCREMENTAL:NO"])
|
||||
|
||||
env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
|
||||
env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding.
|
||||
|
|
|
@ -33,9 +33,19 @@
|
|||
#include "core/input_map.h"
|
||||
#include "core/os/input.h"
|
||||
#include "core/os/os.h"
|
||||
#include "scene/scene_string_names.h"
|
||||
|
||||
void TouchScreenButton::set_texture(const Ref<Texture> &p_texture) {
|
||||
if (texture == p_texture) {
|
||||
return;
|
||||
}
|
||||
if (texture.is_valid()) {
|
||||
texture->disconnect(SceneStringNames::get_singleton()->changed, this, "update");
|
||||
}
|
||||
texture = p_texture;
|
||||
if (texture.is_valid()) {
|
||||
texture->connect(SceneStringNames::get_singleton()->changed, this, "update", varray(), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -44,7 +54,16 @@ Ref<Texture> TouchScreenButton::get_texture() const {
|
|||
}
|
||||
|
||||
void TouchScreenButton::set_texture_pressed(const Ref<Texture> &p_texture_pressed) {
|
||||
if (texture_pressed == p_texture_pressed) {
|
||||
return;
|
||||
}
|
||||
if (texture_pressed.is_valid()) {
|
||||
texture_pressed->disconnect(SceneStringNames::get_singleton()->changed, this, "update");
|
||||
}
|
||||
texture_pressed = p_texture_pressed;
|
||||
if (texture_pressed.is_valid()) {
|
||||
texture_pressed->connect(SceneStringNames::get_singleton()->changed, this, "update", varray(), CONNECT_REFERENCE_COUNTED);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -61,16 +80,16 @@ Ref<BitMap> TouchScreenButton::get_bitmask() const {
|
|||
}
|
||||
|
||||
void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) {
|
||||
if (shape.is_valid()) {
|
||||
shape->disconnect("changed", this, "update");
|
||||
if (shape == p_shape) {
|
||||
return;
|
||||
}
|
||||
if (shape.is_valid()) {
|
||||
shape->disconnect(SceneStringNames::get_singleton()->changed, this, "update");
|
||||
}
|
||||
|
||||
shape = p_shape;
|
||||
|
||||
if (shape.is_valid()) {
|
||||
shape->connect("changed", this, "update");
|
||||
shape->connect(SceneStringNames::get_singleton()->changed, this, "update");
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,11 +67,6 @@ bool AudioEffectRecordInstance::process_silence() const {
|
|||
|
||||
void AudioEffectRecordInstance::_io_thread_process() {
|
||||
while (is_recording) {
|
||||
//Check: The current recording has been requested to stop
|
||||
if (!base->recording_active) {
|
||||
is_recording = false;
|
||||
}
|
||||
|
||||
_update_buffer();
|
||||
|
||||
if (is_recording) {
|
||||
|
@ -119,6 +114,7 @@ void AudioEffectRecordInstance::init() {
|
|||
}
|
||||
|
||||
void AudioEffectRecordInstance::finish() {
|
||||
is_recording = false;
|
||||
#ifdef NO_THREADS
|
||||
AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
|
||||
#else
|
||||
|
@ -126,14 +122,9 @@ void AudioEffectRecordInstance::finish() {
|
|||
#endif
|
||||
}
|
||||
|
||||
AudioEffectRecordInstance::~AudioEffectRecordInstance() {
|
||||
finish();
|
||||
}
|
||||
|
||||
Ref<AudioEffectInstance> AudioEffectRecord::instance() {
|
||||
Ref<AudioEffectRecordInstance> ins;
|
||||
ins.instance();
|
||||
ins->base = Ref<AudioEffectRecord>(this);
|
||||
ins->is_recording = false;
|
||||
|
||||
//Re-using the buffer size calculations from audio_effect_delay.cpp
|
||||
|
@ -159,16 +150,19 @@ Ref<AudioEffectInstance> AudioEffectRecord::instance() {
|
|||
ins->ring_buffer_read_pos = 0;
|
||||
|
||||
ensure_thread_stopped();
|
||||
current_instance = ins;
|
||||
if (recording_active) {
|
||||
bool is_currently_recording = false;
|
||||
if (current_instance != nullptr) {
|
||||
is_currently_recording = current_instance->is_recording;
|
||||
}
|
||||
if (is_currently_recording) {
|
||||
ins->init();
|
||||
}
|
||||
current_instance = ins;
|
||||
|
||||
return ins;
|
||||
}
|
||||
|
||||
void AudioEffectRecord::ensure_thread_stopped() {
|
||||
recording_active = false;
|
||||
if (current_instance != nullptr) {
|
||||
current_instance->finish();
|
||||
}
|
||||
|
@ -178,20 +172,24 @@ void AudioEffectRecord::set_recording_active(bool p_record) {
|
|||
if (p_record) {
|
||||
if (current_instance == nullptr) {
|
||||
WARN_PRINT("Recording should not be set as active before Godot has initialized.");
|
||||
recording_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ensure_thread_stopped();
|
||||
recording_active = true;
|
||||
current_instance->init();
|
||||
} else {
|
||||
recording_active = false;
|
||||
if (current_instance != nullptr) {
|
||||
current_instance->is_recording = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioEffectRecord::is_recording_active() const {
|
||||
return recording_active;
|
||||
if (current_instance != nullptr) {
|
||||
return current_instance->is_recording;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEffectRecord::set_format(AudioStreamSample::Format p_format) {
|
||||
|
@ -289,5 +287,8 @@ void AudioEffectRecord::_bind_methods() {
|
|||
|
||||
AudioEffectRecord::AudioEffectRecord() {
|
||||
format = AudioStreamSample::FORMAT_16_BITS;
|
||||
recording_active = false;
|
||||
}
|
||||
|
||||
AudioEffectRecord::~AudioEffectRecord() {
|
||||
ensure_thread_stopped();
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ class AudioEffectRecord;
|
|||
class AudioEffectRecordInstance : public AudioEffectInstance {
|
||||
GDCLASS(AudioEffectRecordInstance, AudioEffectInstance);
|
||||
friend class AudioEffectRecord;
|
||||
Ref<AudioEffectRecord> base;
|
||||
|
||||
bool is_recording;
|
||||
Thread io_thread;
|
||||
|
@ -68,9 +67,6 @@ public:
|
|||
void finish();
|
||||
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
|
||||
virtual bool process_silence() const;
|
||||
|
||||
AudioEffectRecordInstance() {}
|
||||
~AudioEffectRecordInstance();
|
||||
};
|
||||
|
||||
class AudioEffectRecord : public AudioEffect {
|
||||
|
@ -82,7 +78,6 @@ class AudioEffectRecord : public AudioEffect {
|
|||
IO_BUFFER_SIZE_MS = 1500
|
||||
};
|
||||
|
||||
bool recording_active;
|
||||
Ref<AudioEffectRecordInstance> current_instance;
|
||||
|
||||
AudioStreamSample::Format format;
|
||||
|
@ -101,6 +96,7 @@ public:
|
|||
Ref<AudioStreamSample> get_recording() const;
|
||||
|
||||
AudioEffectRecord();
|
||||
~AudioEffectRecord();
|
||||
};
|
||||
|
||||
#endif // AUDIO_EFFECT_RECORD_H
|
||||
|
|
Loading…
Reference in New Issue