From da2c5abfdd75701720999bc8dd4feec5a08eec42 Mon Sep 17 00:00:00 2001 From: gilzoide Date: Sun, 12 Jan 2025 09:26:31 -0300 Subject: [PATCH] Fix support for async API on WebGL platforms --- Plugins/tools~/fix-library-path.sed | 3 +++ README.md | 1 + Runtime/SQLiteAsyncExtensions.cs | 23 +++++++++++++++++++++++ Runtime/SQLiteAsyncExtensions.cs.meta | 11 +++++++++++ Runtime/sqlite-net/SQLiteAsync.cs | 12 ++++++------ 5 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 Runtime/SQLiteAsyncExtensions.cs create mode 100644 Runtime/SQLiteAsyncExtensions.cs.meta diff --git a/Plugins/tools~/fix-library-path.sed b/Plugins/tools~/fix-library-path.sed index 9e7ed28..9406e7e 100644 --- a/Plugins/tools~/fix-library-path.sed +++ b/Plugins/tools~/fix-library-path.sed @@ -34,3 +34,6 @@ s/class SQLite3/partial class SQLite3/ # Add [RequiredMember] attribute to ColumnInfo.Name property # This fixes managed code stripping removing its setter method s/Column ("name")/Column ("name"), UnityEngine.Scripting.RequiredMember/ + +# Use main thread TaskScheduler in WebGL +s/TaskScheduler\.Default/SQLiteAsyncExtensions.TaskScheduler/ diff --git a/README.md b/README.md index a2c34e0..74b3dd0 100644 --- a/README.md +++ b/README.md @@ -114,3 +114,4 @@ Third-party code: This is be useful for libraries making raw queries. - `SQLite3.SetDirectory` is only defined in Windows platforms. - Adds a `[RequiredMember]` attribute to `ColumnInfo.Name` property, fixing errors on columns when managed code stripping is enabled. +- Changes the `TaskScheduler` used by the async API on WebGL to one that executes tasks on Unity's main thread. diff --git a/Runtime/SQLiteAsyncExtensions.cs b/Runtime/SQLiteAsyncExtensions.cs new file mode 100644 index 0000000..647e1c2 --- /dev/null +++ b/Runtime/SQLiteAsyncExtensions.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using UnityEngine; + +namespace SQLite +{ + public static class SQLiteAsyncExtensions + { +#if UNITY_WEBGL + // WebGL builds cannot use background threads, so use a + // TaskScheduler that executes tasks on Unity's main thread. + public static TaskScheduler TaskScheduler { get; private set; } + + [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] + private static void InitializeTaskScheduler() + { + TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); + } +#else + // On all other platforms, use the default TaskScheduler + public static TaskScheduler TaskScheduler => TaskScheduler.Default; +#endif + } +} diff --git a/Runtime/SQLiteAsyncExtensions.cs.meta b/Runtime/SQLiteAsyncExtensions.cs.meta new file mode 100644 index 0000000..dc395ae --- /dev/null +++ b/Runtime/SQLiteAsyncExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da6b73f57890c4a9ca69e882cd03e45e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/sqlite-net/SQLiteAsync.cs b/Runtime/sqlite-net/SQLiteAsync.cs index c18eea2..d297d61 100644 --- a/Runtime/sqlite-net/SQLiteAsync.cs +++ b/Runtime/sqlite-net/SQLiteAsync.cs @@ -215,7 +215,7 @@ public Task CloseAsync () { return Task.Factory.StartNew (() => { SQLiteConnectionPool.Shared.CloseConnection (_connectionString); - }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, SQLiteAsyncExtensions.TaskScheduler); } Task ReadAsync (Func read) @@ -225,7 +225,7 @@ Task ReadAsync (Func read) using (conn.Lock ()) { return read (conn); } - }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, SQLiteAsyncExtensions.TaskScheduler); } Task WriteAsync (Func write) @@ -235,7 +235,7 @@ Task WriteAsync (Func write) using (conn.Lock ()) { return write (conn); } - }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, SQLiteAsyncExtensions.TaskScheduler); } Task TransactAsync (Func transact) @@ -247,7 +247,7 @@ Task TransactAsync (Func transact) return transact (conn); } } - }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, SQLiteAsyncExtensions.TaskScheduler); } /// @@ -1201,7 +1201,7 @@ Task ReadAsync (Func read) using (conn.Lock ()) { return read (conn); } - }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, SQLiteAsyncExtensions.TaskScheduler); } Task WriteAsync (Func write) @@ -1211,7 +1211,7 @@ Task WriteAsync (Func write) using (conn.Lock ()) { return write (conn); } - }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, SQLiteAsyncExtensions.TaskScheduler); } ///