-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathAsyncLoadingLibrary.h
144 lines (116 loc) · 5.92 KB
/
AsyncLoadingLibrary.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright 2018 Jack Knobel. All Rights Reserved.
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Engine/LatentActionManager.h"
#include "Engine/StreamableManager.h"
#include "AsyncLoadingLibrary.generated.h"
struct FBundleAsset
{
private:
FSoftObjectPath ObjectPath;
public:
template<typename TSoftAsset>
FBundleAsset(const TSoftAsset& asset)
: ObjectPath(asset.ToSoftObjectPath())
{}
FBundleAsset(const FSoftObjectPath& asset)
: ObjectPath(asset)
{}
inline const FSoftObjectPath& GetPath() const { return ObjectPath; }
inline const UObject* GetObject() const { return ObjectPath.ResolveObject(); }
bool operator==(const FBundleAsset& other) const
{
return ObjectPath == other.ObjectPath;
}
bool operator==(const FSoftObjectPath& other) const
{
return ObjectPath == other;
}
};
using FAssetBundle = TArray<FBundleAsset>;
struct FAsyncLoadBundle
{
// Objects we would like to load
FAssetBundle ObjectBundle;
// A callback function for the loading of the bundle
FStreamableDelegate CallbackDelegate;
FAsyncLoadBundle(const FAssetBundle& objectsToLoad, const FStreamableDelegate& loadCompleteCallback = FStreamableDelegate())
: ObjectBundle(objectsToLoad), CallbackDelegate(loadCompleteCallback)
{}
template<typename TAsset>
inline bool AddAssetToLoad(const TAsset& asset)
{
ObjectBundle.Emplace(asset.ToSoftObjectPath());
}
inline bool AddAssetToLoad(const FSoftObjectPath& asset)
{
ObjectBundle.Emplace(asset);
}
inline bool AddAssetsToLoad(const FAssetBundle& assets)
{
ObjectBundle.Append(assets);
}
void TriggerLoad(TAsyncLoadPriority loadPriority = 50, const FString& debugName = TEXT("LoadAsyncBundle"));
};
/**
*
*/
UCLASS()
class UAsyncLoadingLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnAssetsLoaded, const TArray<UObject*>&, LoadedAssets);
/* Asynchronously load a Set of Soft Object Paths with the option to bind to a delegate to be notified when the loading is complete.
* Delegate returns an Array of Loaded UObject's however you are safe to use the original Soft Objects as they will be loaded
*/
UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "latentAction", WorldContext = "WorldContextObject", AutoCreateRefTerm = "onAssetsLoaded"), Category = AsyncLoadingLibrary)
static void AsyncLoadAnyAssets(UObject* worldContextObject, const TSet<FSoftObjectPath>& assets, const FOnAssetsLoaded& onAssetsLoaded, FLatentActionInfo latentAction);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AutoCreateRefTerm = "onAssetsLoaded"), Category = AsyncLoadingLibrary)
static void AsyncLoadAnyAssets_Event(UObject* worldContextObject, const TSet<FSoftObjectPath>& assets, const FOnAssetsLoaded& onAssetsLoaded)
{
FLatentActionInfo latentAction;
latentAction.CallbackTarget = worldContextObject;
AsyncLoadAnyAssets(worldContextObject, assets, onAssetsLoaded, latentAction);
}
/* Asynchronously load a Set of Soft Object Ptrs with the option to bind to a delegate to be notified when the loading is complete
* Delegate returns an Array of Loaded UObject's however you are safe to use the original Soft Objects as they will be loaded
*/
UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "latentAction", WorldContext = "WorldContextObject", AutoCreateRefTerm = "onAssetsLoaded"), Category = AsyncLoadingLibrary)
static void AsyncLoadAssets(UObject* worldContextObject, const TSet<TSoftObjectPtr<UObject>>& assets, const FOnAssetsLoaded& onAssetsLoaded, FLatentActionInfo latentAction);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AutoCreateRefTerm = "onAssetsLoaded"), Category = AsyncLoadingLibrary)
static void AsyncLoadAssets_Event(UObject* worldContextObject, const TSet<TSoftObjectPtr<UObject>>& assets, const FOnAssetsLoaded& onAssetsLoaded)
{
FLatentActionInfo latentAction;
latentAction.CallbackTarget = worldContextObject;
AsyncLoadAssets(worldContextObject, assets, onAssetsLoaded, latentAction);
}
/* Asynchronously load a Set of Soft Class Ptrs with the option to bind to a delegate to be notified when the loading is complete
* Delegate returns an Array of Loaded UObject's however you are safe to use the original Soft Objects as they will be loaded
*/
UFUNCTION(BlueprintCallable, meta = (Latent, LatentInfo = "latentAction", WorldContext = "WorldContextObject", AutoCreateRefTerm = "onAssetsLoaded"), Category = AsyncLoadingLibrary)
static void AsyncLoadClasses(UObject* worldContextObject, const TSet<TSoftClassPtr<UObject>>& assets, const FOnAssetsLoaded& onAssetsLoaded, FLatentActionInfo latentAction);
UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", AutoCreateRefTerm = "onAssetsLoaded"), Category = AsyncLoadingLibrary)
static void AsyncLoadClasses_Event(UObject* worldContextObject, const TSet<TSoftClassPtr<UObject>>& assets, const FOnAssetsLoaded& onAssetsLoaded)
{
FLatentActionInfo latentAction;
latentAction.CallbackTarget = worldContextObject;
AsyncLoadClasses(worldContextObject, assets, onAssetsLoaded, latentAction);
}
//////////////////////////////////////////////////////////////////////////
// Helper Functions
//////////////////////////////////////////////////////////////////////////
UFUNCTION(BlueprintPure, Category = AsyncLoadingLibrary)
static inline FSoftObjectPath SoftObjectPtrToSoftObjectPath(const TSoftObjectPtr<UObject>& asset) { return asset.ToSoftObjectPath(); }
UFUNCTION(BlueprintPure, Category = AsyncLoadingLibrary)
static inline FSoftObjectPath SoftClassPtrToSoftObjectPath(const TSoftClassPtr<UObject>& asset) { return asset.ToSoftObjectPath(); }
template<typename TSoftAsset>
static void ConvertSoftPtrSetToSoftObjectPathArray(const TSet<TSoftAsset>& assets, TArray<FSoftObjectPath>& outSoftObjectPaths)
{
outSoftObjectPaths.Reserve(outSoftObjectPaths.Num() + assets.Num());
for (const auto& asset : assets)
{
outSoftObjectPaths.Emplace(asset.ToSoftObjectPath());
}
}
};