mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Reprocess, load and hot swap changed assets using new asset pipeline
This commit is contained in:
@@ -63,6 +63,8 @@ class AssetFile
|
|||||||
|
|
||||||
public EditorContentManager ContentManager => _contentManager;
|
public EditorContentManager ContentManager => _contentManager;
|
||||||
|
|
||||||
|
public bool UseNewAssetPipeline => _assetConfig?.ImporterConfig != null;
|
||||||
|
|
||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this(EditorContentManager contentManager, AssetNode assetNode)
|
public this(EditorContentManager contentManager, AssetNode assetNode)
|
||||||
{
|
{
|
||||||
@@ -82,24 +84,32 @@ class AssetFile
|
|||||||
{
|
{
|
||||||
AssetFile assetFile = new AssetFile(contentManager, assetNode);
|
AssetFile assetFile = new AssetFile(contentManager, assetNode);
|
||||||
|
|
||||||
assetFile.LoadOrCreateAssetConfig();
|
assetFile.CheckForReprocessing();
|
||||||
|
|
||||||
// TODO: Remove this check once we only use the new processing pipeline
|
|
||||||
if (assetFile._assetConfig.ImporterConfig != null)
|
|
||||||
{
|
|
||||||
CachedAsset cacheEntry = assetFile._contentManager.AssetCache.GetCacheEntry(assetFile._assetConfig.AssetHandle);
|
|
||||||
|
|
||||||
if (cacheEntry == null ||
|
|
||||||
cacheEntry.CreationTimestamp < assetFile._lastAssetEditTime ||
|
|
||||||
cacheEntry.CreationTimestamp < assetFile._lastConfigEditTime)
|
|
||||||
{
|
|
||||||
assetFile._contentManager.AssetConverter.QueueForProcessing(assetFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return assetFile;
|
return assetFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CheckForReprocessing()
|
||||||
|
{
|
||||||
|
LoadOrCreateAssetConfig();
|
||||||
|
|
||||||
|
// TODO: Remove this check once we only use the new processing pipeline
|
||||||
|
if (!UseNewAssetPipeline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CachedAsset cacheEntry = _contentManager.AssetCache.GetCacheEntry(_assetConfig.AssetHandle);
|
||||||
|
|
||||||
|
_lastAssetEditTime = File.GetLastWriteTimeUtc(_assetFile.Path);
|
||||||
|
_lastConfigEditTime = File.GetLastWriteTimeUtc(_assetConfigPath);
|
||||||
|
|
||||||
|
if (cacheEntry == null ||
|
||||||
|
cacheEntry.CreationTimestamp < _lastAssetEditTime ||
|
||||||
|
cacheEntry.CreationTimestamp < _lastConfigEditTime)
|
||||||
|
{
|
||||||
|
_contentManager.AssetConverter.QueueForProcessing(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Loads the asset config (.ass) file or creates it.
|
/// Loads the asset config (.ass) file or creates it.
|
||||||
private void LoadOrCreateAssetConfig()
|
private void LoadOrCreateAssetConfig()
|
||||||
{
|
{
|
||||||
@@ -107,12 +117,12 @@ class AssetFile
|
|||||||
{
|
{
|
||||||
LoadAssetConfig();
|
LoadAssetConfig();
|
||||||
}
|
}
|
||||||
else
|
else if (_assetConfig == null)
|
||||||
{
|
{
|
||||||
CreateDefaultAssetLoader();
|
CreateDefaultAssetLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastAssetEditTime = File.GetLastWriteTimeUtc(_assetConfigPath);
|
_lastConfigEditTime = File.GetLastWriteTimeUtc(_assetConfigPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateAssetHandle()
|
private void GenerateAssetHandle()
|
||||||
@@ -123,7 +133,9 @@ class AssetFile
|
|||||||
private void CreateDefaultAssetLoader()
|
private void CreateDefaultAssetLoader()
|
||||||
{
|
{
|
||||||
String fileExtension = Path.GetExtension(_assetFile.Path, .. scope .());
|
String fileExtension = Path.GetExtension(_assetFile.Path, .. scope .());
|
||||||
|
|
||||||
|
Log.EngineLogger.Info($"Created config for {_assetFile.Path}");
|
||||||
|
|
||||||
_assetConfig = new AssetConfig();
|
_assetConfig = new AssetConfig();
|
||||||
|
|
||||||
GenerateAssetHandle();
|
GenerateAssetHandle();
|
||||||
@@ -163,21 +175,33 @@ class AssetFile
|
|||||||
|
|
||||||
private void LoadAssetConfig()
|
private void LoadAssetConfig()
|
||||||
{
|
{
|
||||||
if (Bon.DeserializeFromFile(ref _assetConfig, _assetConfigPath) case .Err)
|
AssetConfig newAssetConfig = new AssetConfig();
|
||||||
|
|
||||||
|
if (Bon.DeserializeFromFile(ref newAssetConfig, _assetConfigPath) case .Err)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Failed to load asset config {_assetConfigPath}");
|
Log.EngineLogger.Error($"Failed to load asset config {_assetConfigPath}");
|
||||||
|
|
||||||
// TODO: Handle failure of asset config loading
|
delete newAssetConfig;
|
||||||
Runtime.NotImplemented();
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete _assetConfig;
|
||||||
|
_assetConfig = newAssetConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveAssetConfig()
|
public void SaveAssetConfig()
|
||||||
{
|
{
|
||||||
gBonEnv.serializeFlags |= .Verbose;
|
//BonEnvironment bonEnv = scope .();
|
||||||
|
|
||||||
|
var oldFlags = gBonEnv.serializeFlags;
|
||||||
|
|
||||||
|
gBonEnv.serializeFlags |= .IncludeDefault | .Verbose;
|
||||||
|
|
||||||
Bon.SerializeIntoFile(_assetConfig, _assetConfigPath);
|
Bon.SerializeIntoFile(_assetConfig, _assetConfigPath);
|
||||||
|
|
||||||
_assetConfig.Config.[Friend]_changed = false;
|
_assetConfig.Config?.[Friend]_changed = false;
|
||||||
|
|
||||||
|
gBonEnv.serializeFlags = oldFlags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,14 +35,21 @@ class AssetCache
|
|||||||
/// Current format version of loose asset file (.laf) file reader and writer.
|
/// Current format version of loose asset file (.laf) file reader and writer.
|
||||||
public const uint16 FormatVersion = 1;
|
public const uint16 FormatVersion = 1;
|
||||||
|
|
||||||
private append String _directory = .() ~ delete:append _;
|
private append String _directory = .();// ~ delete:append _;
|
||||||
|
|
||||||
private append Dictionary<AssetHandle, CachedAsset> _assets ~ delete:append _;
|
private append Dictionary<AssetHandle, CachedAsset> _assets = .();// ~ delete:append _;
|
||||||
|
|
||||||
public StringView CacheDirectory => _directory;
|
public StringView CacheDirectory => _directory;
|
||||||
|
|
||||||
private bool _cacheLoaded;
|
private bool _cacheLoaded;
|
||||||
|
|
||||||
|
private EditorContentManager _contentManager;
|
||||||
|
|
||||||
|
public this(EditorContentManager contentManager)
|
||||||
|
{
|
||||||
|
_contentManager = contentManager;
|
||||||
|
}
|
||||||
|
|
||||||
public ~this()
|
public ~this()
|
||||||
{
|
{
|
||||||
ClearCache();
|
ClearCache();
|
||||||
@@ -198,7 +205,7 @@ class AssetCache
|
|||||||
|
|
||||||
switch (asset.Compression)
|
switch (asset.Compression)
|
||||||
{
|
{
|
||||||
case .L4Z:
|
case .LZ4:
|
||||||
uint maxCompressedSize = LZ4.LZ4F_CompressFrameBound((uint)data.Length);
|
uint maxCompressedSize = LZ4.LZ4F_CompressFrameBound((uint)data.Length);
|
||||||
|
|
||||||
uint8[] compressedData = new uint8[maxCompressedSize];
|
uint8[] compressedData = new uint8[maxCompressedSize];
|
||||||
@@ -233,7 +240,7 @@ class AssetCache
|
|||||||
|
|
||||||
Try!(writer.Write(dataToWrite));
|
Try!(writer.Write(dataToWrite));
|
||||||
|
|
||||||
// TODO: Notify content manager!
|
_contentManager.QueueAssetReload(asset.Handle);
|
||||||
|
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
@@ -262,7 +269,7 @@ class AssetCache
|
|||||||
FileStream fileStream = new FileStream();
|
FileStream fileStream = new FileStream();
|
||||||
Try!(OpenFileStream(asset, fileStream));
|
Try!(OpenFileStream(asset, fileStream));
|
||||||
return fileStream;
|
return fileStream;
|
||||||
case .L4Z:
|
case .LZ4:
|
||||||
FileStream compressedStream = scope FileStream();
|
FileStream compressedStream = scope FileStream();
|
||||||
Try!(OpenFileStream(asset, compressedStream));
|
Try!(OpenFileStream(asset, compressedStream));
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ class AssetHierarchy
|
|||||||
private append String _resourcesDirectory = .();
|
private append String _resourcesDirectory = .();
|
||||||
private append String _assetsDirectory = .();
|
private append String _assetsDirectory = .();
|
||||||
|
|
||||||
|
private const float FileSystemDebounceSeconds = 0.5f;
|
||||||
|
|
||||||
private EditorContentManager _contentManager;
|
private EditorContentManager _contentManager;
|
||||||
|
|
||||||
public TreeNode<AssetNode> RootNode => _assetRootNode;
|
public TreeNode<AssetNode> RootNode => _assetRootNode;
|
||||||
@@ -257,21 +259,31 @@ class AssetHierarchy
|
|||||||
|
|
||||||
private bool _fileTreeUpdateRequested = false;
|
private bool _fileTreeUpdateRequested = false;
|
||||||
|
|
||||||
|
private float _fileSystemDebounce;
|
||||||
|
|
||||||
/// Invokes the the file tree update on the mainthread.
|
/// Invokes the the file tree update on the mainthread.
|
||||||
private void DeferFileTreeUpdate()
|
private void DeferFileTreeUpdate()
|
||||||
{
|
{
|
||||||
|
_fileSystemDebounce = FileSystemDebounceSeconds;
|
||||||
|
|
||||||
if (!_fileTreeUpdateRequested)
|
if (!_fileTreeUpdateRequested)
|
||||||
{
|
{
|
||||||
_fileTreeUpdateRequested = true;
|
_fileTreeUpdateRequested = true;
|
||||||
|
|
||||||
Application.Instance.InvokeOnMainThread(new () =>
|
Application.Instance.InvokeOnMainThread(new () =>
|
||||||
{
|
{
|
||||||
|
_fileSystemDebounce -= Application.Instance.GameTime.DeltaTime;
|
||||||
|
|
||||||
|
if (_fileSystemDebounce > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
UpdateFiles();
|
UpdateFiles();
|
||||||
_fileTreeUpdateRequested = false;
|
_fileTreeUpdateRequested = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the FSW for the current ContentDirectory and registers the events.
|
/// Initializes the FSW for the current ContentDirectory and registers the events.
|
||||||
private void SetupFileSystemWatcher()
|
private void SetupFileSystemWatcher()
|
||||||
{
|
{
|
||||||
@@ -518,7 +530,7 @@ class AssetHierarchy
|
|||||||
fileName.RemoveFromEnd(AssetFile.ConfigFileExtension.Length);
|
fileName.RemoveFromEnd(AssetFile.ConfigFileExtension.Length);
|
||||||
|
|
||||||
String fileNameWithContentRoot = scope .();
|
String fileNameWithContentRoot = scope .();
|
||||||
Path.InternalCombine(fileNameWithContentRoot, _assetsDirectory, fileName);
|
Path.Combine(fileNameWithContentRoot, _assetsDirectory, fileName);
|
||||||
|
|
||||||
var nodeResult = GetNodeFromPath(fileNameWithContentRoot);
|
var nodeResult = GetNodeFromPath(fileNameWithContentRoot);
|
||||||
|
|
||||||
@@ -535,7 +547,21 @@ class AssetHierarchy
|
|||||||
if (node->IsDirectory)
|
if (node->IsDirectory)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnFileContentChanged(node.Value);
|
if (!(node->AssetFile?.UseNewAssetPipeline ?? false))
|
||||||
|
OnFileContentChanged(node.Value);
|
||||||
|
|
||||||
|
_fileSystemDebounce = FileSystemDebounceSeconds;
|
||||||
|
|
||||||
|
Application.Instance.InvokeOnMainThread(new () => {
|
||||||
|
_fileSystemDebounce -= Application.Instance.GameTime.DeltaTime;
|
||||||
|
if (_fileSystemDebounce > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
node->AssetFile?.CheckForReprocessing();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FileRenamed(StringView oldFilePath, StringView newFilePath)
|
private void FileRenamed(StringView oldFilePath, StringView newFilePath)
|
||||||
@@ -546,7 +572,6 @@ class AssetHierarchy
|
|||||||
if (oldFilePath.EndsWith(AssetFile.ConfigFileExtension))
|
if (oldFilePath.EndsWith(AssetFile.ConfigFileExtension))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
String oldFileNameWithContentRoot = scope .();
|
String oldFileNameWithContentRoot = scope .();
|
||||||
Path.InternalCombine(oldFileNameWithContentRoot, _assetsDirectory, oldFilePath);
|
Path.InternalCombine(oldFileNameWithContentRoot, _assetsDirectory, oldFilePath);
|
||||||
|
|
||||||
@@ -560,7 +585,10 @@ class AssetHierarchy
|
|||||||
|
|
||||||
if (File.Exists(oldConfigFileName) && !File.Exists(newConfigFileName))
|
if (File.Exists(oldConfigFileName) && !File.Exists(newConfigFileName))
|
||||||
{
|
{
|
||||||
if (File.Move(oldConfigFileName, newConfigFileName) case .Err(let value))
|
// TODO: Actually Move, but it's a bit complicated to manage cases, where external programs move the original file and
|
||||||
|
// rename an new file to the original name. So just copy the config to retain it.
|
||||||
|
// I don't think there is a clean way to solve this.
|
||||||
|
if (File.Copy(oldConfigFileName, newConfigFileName) case .Err(let value))
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Failed to move file {oldConfigFileName} to {newConfigFileName}. Code: {value}");
|
Log.EngineLogger.Error($"Failed to move file {oldConfigFileName} to {newConfigFileName}. Code: {value}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ class TextureImporter : IAssetImporter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
enum GenerateMipMaps
|
enum GenerateMipMaps
|
||||||
{
|
{
|
||||||
No,
|
No,
|
||||||
@@ -717,7 +718,10 @@ class TextureLoader : IProcessedAssetLoader
|
|||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
result.SamplerState = SamplerStateManager.GetSampler(sampler);
|
using (SamplerState samplerState = SamplerStateManager.GetSampler(sampler))
|
||||||
|
{
|
||||||
|
result.SamplerState = samplerState;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ class TextureAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
public override void ShowEditor()
|
public override void ShowEditor()
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
|
||||||
if (_textureConfig == null)
|
if (_textureConfig == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ class PropertiesWindow : EditorWindow
|
|||||||
|
|
||||||
private void ShowPropertiesEditor(AssetFile assetFile)
|
private void ShowPropertiesEditor(AssetFile assetFile)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
|
||||||
if (_currentPropertiesEditor == null)
|
if (_currentPropertiesEditor == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class EditorContentManager : IContentManager
|
|||||||
private append Dictionary<AssetHandle, Asset> _handleToAsset = .();
|
private append Dictionary<AssetHandle, Asset> _handleToAsset = .();
|
||||||
|
|
||||||
private append AssetHierarchy _assetHierarchy = .(this);
|
private append AssetHierarchy _assetHierarchy = .(this);
|
||||||
private append AssetCache _assetCache = .() ~ delete:append _;
|
private append AssetCache _assetCache = .(this);
|
||||||
private append AssetConverter _assetConverter = .(this);
|
private append AssetConverter _assetConverter = .(this);
|
||||||
|
|
||||||
private append List<AssetHandle> _reloadQueue = .();
|
private append List<AssetHandle> _reloadQueue = .();
|
||||||
@@ -54,9 +54,18 @@ class EditorContentManager : IContentManager
|
|||||||
if (assetNode.AssetFile?.LoadedAsset == null)
|
if (assetNode.AssetFile?.LoadedAsset == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_reloadQueue.Add(assetNode.AssetFile.LoadedAsset.Handle);
|
QueueAssetReload(assetNode.AssetFile.LoadedAsset.Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void QueueAssetReload(AssetHandle assetHandle)
|
||||||
|
{
|
||||||
|
// The asset isn't loaded, so we don't need to reload.
|
||||||
|
if (!_handleToAsset.ContainsKey(assetHandle))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_reloadQueue.Add(assetHandle);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnFileRenamed(AssetNode assetNode, StringView oldIdentifier)
|
public void OnFileRenamed(AssetNode assetNode, StringView oldIdentifier)
|
||||||
{
|
{
|
||||||
// Asset isn't loaded so we don't need to reload it.
|
// Asset isn't loaded so we don't need to reload it.
|
||||||
@@ -373,33 +382,45 @@ class EditorContentManager : IContentManager
|
|||||||
|
|
||||||
Log.EngineLogger.AssertDebug(oldAsset != null);
|
Log.EngineLogger.AssertDebug(oldAsset != null);
|
||||||
|
|
||||||
StringView oldIdentifier = oldAsset.Identifier;
|
|
||||||
|
|
||||||
GetResourceAndSubassetName(oldIdentifier, let resourceName, let subassetName);
|
|
||||||
|
|
||||||
Result<TreeNode<AssetNode>> resultNode = AssetHierarchy.GetNodeFromAssetHandle(handle);
|
Result<TreeNode<AssetNode>> resultNode = AssetHierarchy.GetNodeFromAssetHandle(handle);
|
||||||
|
|
||||||
if (resultNode case .Err)
|
if (resultNode case .Err)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Could not find asset node for asset \"{oldIdentifier}\".");
|
Log.EngineLogger.Error($"Could not find asset node for asset \"{oldAsset.Identifier}\".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetNode assetNode = resultNode->Value;
|
AssetNode assetNode = resultNode->Value;
|
||||||
AssetFile file = assetNode.AssetFile;
|
AssetFile file = assetNode.AssetFile;
|
||||||
|
|
||||||
|
CachedAsset cacheEntry = _assetCache.GetCacheEntry(handle);
|
||||||
|
|
||||||
|
Asset loadedAsset;
|
||||||
|
|
||||||
|
// TODO: Remove this check once we no longer need the old stuff
|
||||||
|
if (cacheEntry != null)
|
||||||
|
{
|
||||||
|
loadedAsset = LoadFromCache(handle, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IAssetLoader assetLoader = GetAssetLoader(file);
|
||||||
|
|
||||||
|
Stream stream = OpenStream(assetNode.Path, true);
|
||||||
|
|
||||||
|
StringView oldIdentifier = oldAsset.Identifier;
|
||||||
|
|
||||||
|
GetResourceAndSubassetName(oldIdentifier, let resourceName, let subassetName);
|
||||||
|
|
||||||
|
// TODO: Add async loading!
|
||||||
|
loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
|
||||||
|
|
||||||
IAssetLoader assetLoader = GetAssetLoader(file);
|
delete stream;
|
||||||
|
}
|
||||||
Stream stream = OpenStream(assetNode.Path, true);
|
|
||||||
|
|
||||||
// TODO: Add async loading!
|
|
||||||
Asset loadedAsset = assetLoader.LoadAsset(stream, file.AssetConfig.Config, resourceName, subassetName, this);
|
|
||||||
|
|
||||||
delete stream;
|
|
||||||
|
|
||||||
if (loadedAsset == null)
|
if (loadedAsset == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
file.[Friend]_loadedAsset = loadedAsset;
|
file.[Friend]_loadedAsset = loadedAsset;
|
||||||
|
|
||||||
SwapAsset(oldAsset, loadedAsset);
|
SwapAsset(oldAsset, loadedAsset);
|
||||||
@@ -910,7 +931,7 @@ class EditorContentManager : IContentManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: obviously use a map or something...
|
// TODO: obviously use a map or something...
|
||||||
TextureLoader textureLoader = new .();
|
TextureLoader textureLoader = new .() ~ delete _;
|
||||||
|
|
||||||
private IProcessedAssetLoader GetLoader(AssetType assetType)
|
private IProcessedAssetLoader GetLoader(AssetType assetType)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
private IContentManager _contentManager;
|
private IContentManager _contentManager;
|
||||||
|
|
||||||
private append List<delegate void()> _jobQueue = .() ~ ClearAndDeleteItems!(_);
|
private append List<delegate bool()> _jobQueue = .() ~ ClearAndDeleteItems!(_);
|
||||||
private append Monitor _jobQueueMutex = .();
|
private append Monitor _jobQueueMutex = .();
|
||||||
|
|
||||||
public bool IsRunning => _running;
|
public bool IsRunning => _running;
|
||||||
@@ -233,7 +233,7 @@ namespace GlitchyEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Executes the given Job on the main thread. Takes ownership of the delegate.
|
/// Executes the given Job on the main thread. Takes ownership of the delegate.
|
||||||
public void InvokeOnMainThread(delegate void() ownJob)
|
public void InvokeOnMainThread(delegate bool() ownJob)
|
||||||
{
|
{
|
||||||
using (_jobQueueMutex.Enter())
|
using (_jobQueueMutex.Enter())
|
||||||
{
|
{
|
||||||
@@ -249,10 +249,14 @@ namespace GlitchyEngine
|
|||||||
{
|
{
|
||||||
for (let job in _jobQueue)
|
for (let job in _jobQueue)
|
||||||
{
|
{
|
||||||
job();
|
if (job())
|
||||||
|
{
|
||||||
|
@job.RemoveFast();
|
||||||
|
delete job;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearAndDeleteItems!(_jobQueue);
|
//ClearAndDeleteItems!(_jobQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
using Bon;
|
||||||
|
|
||||||
namespace GlitchyEngine.Content;
|
namespace GlitchyEngine.Content;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
enum AssetCompression : uint8
|
enum AssetCompression : uint8
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
L4Z
|
LZ4
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,6 +257,8 @@ static class ScriptEngine
|
|||||||
|
|
||||||
_requestingReload = false;
|
_requestingReload = false;
|
||||||
_userAssemblyWatcher.StartRaisingEvents();
|
_userAssemblyWatcher.StartRaisingEvents();
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user