Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_RESOURCES_ASSETS_XLASSETLIBRARY_H_
24 : #define XENOLITH_RESOURCES_ASSETS_XLASSETLIBRARY_H_
25 :
26 : #include "XLAsset.h"
27 : #include "XLEventHeader.h"
28 : #include "XLStorageServer.h"
29 : #include "XLStorageComponent.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::xenolith::storage {
32 :
33 : class AssetComponent;
34 :
35 : class AssetComponentContainer : public ComponentContainer {
36 : public:
37 42 : virtual ~AssetComponentContainer() { }
38 :
39 : virtual bool init(StringView, AssetLibrary *);
40 :
41 : virtual void handleStorageInit(storage::ComponentLoader &loader) override;
42 : virtual void handleStorageDisposed(const db::Transaction &t) override;
43 :
44 63 : AssetLibrary *getLibrary() const { return _library; }
45 126 : AssetComponent *getComponent() const { return _component; }
46 :
47 : protected:
48 : AssetLibrary *_library = nullptr;
49 : AssetComponent *_component = nullptr;
50 : };
51 :
52 :
53 : class AssetLibrary : public ApplicationExtension {
54 : public:
55 : static EventHeader onLoaded;
56 :
57 : using AssetCallback = Function<void (const Rc<Asset> &)>;
58 : using AssetVecCallback = Function<void (const SpanView<Rc<Asset>> &)>;
59 : using TaskCallback = Function<bool(const Server &, const db::Transaction &)>;
60 :
61 : struct AssetRequest {
62 : String url;
63 : AssetCallback callback;
64 : TimeInterval ttl;
65 : Rc<Ref> ref;
66 :
67 21 : AssetRequest(StringView url, AssetCallback &&cb, TimeInterval ttl, Rc<Ref> &&ref)
68 21 : : url(AssetLibrary::getAssetUrl(url)), callback(move(cb)), ttl(ttl), ref(move(ref)) { }
69 : };
70 :
71 : struct AssetMultiRequest {
72 : Vector<AssetRequest> vec;
73 : AssetVecCallback callback;
74 : Rc<Ref> ref;
75 :
76 0 : AssetMultiRequest(Vector<AssetRequest> &&vec, AssetVecCallback &&cb, Rc<Ref> &&ref)
77 0 : : vec(move(vec)), callback(move(cb)), ref(move(ref)) { }
78 : };
79 :
80 : static String getAssetPath(int64_t);
81 : static String getAssetUrl(StringView);
82 :
83 : virtual ~AssetLibrary();
84 :
85 : bool init(Application *, network::Controller *, const Value &dbParams);
86 :
87 : virtual void initialize(Application *) override;
88 : virtual void invalidate(Application *) override;
89 :
90 : virtual void update(Application *, const UpdateTime &t) override;
91 :
92 : bool acquireAsset(StringView url, AssetCallback &&cb, TimeInterval ttl = TimeInterval(), Rc<Ref> && = nullptr);
93 : bool acquireAssets(SpanView<AssetRequest>, AssetVecCallback && = nullptr, Rc<Ref> && = nullptr);
94 :
95 : Asset *getLiveAsset(StringView) const;
96 : Asset *getLiveAsset(int64_t) const;
97 :
98 : bool perform(TaskCallback &&, Ref * = nullptr) const;
99 :
100 42 : Application *getApplication() const { return _application; }
101 21 : network::Controller *getController() const { return _controller; }
102 :
103 : protected:
104 : friend class Asset;
105 : friend class AssetComponent;
106 :
107 : int64_t addVersion(const db::Transaction &t, int64_t assetId, const Asset::VersionData &);
108 : void eraseVersion(int64_t);
109 :
110 : void setAssetDownload(int64_t id, bool value);
111 : void setVersionComplete(int64_t id, bool value);
112 :
113 : void removeAsset(Asset *);
114 :
115 : network::Handle * downloadAsset(Asset *);
116 :
117 : void cleanup();
118 :
119 : void handleLibraryLoaded(Vector<Rc<Asset>> &&assets);
120 : void handleAssetLoaded(Rc<Asset> &&);
121 :
122 : Rc<AssetComponentContainer> _container;
123 :
124 : bool _loaded = false;
125 : Map<String, Vector<Pair<AssetCallback, Rc<Ref>>>> _callbacks;
126 :
127 : Vector<Rc<Asset>> _liveAssets;
128 : Map<StringView, Asset *> _assetsByUrl;
129 : Map<uint64_t, Asset *> _assetsById;
130 :
131 : Application *_application = nullptr;
132 : network::Controller *_controller = nullptr;
133 : Rc<Server> _server;
134 :
135 : Vector<AssetRequest> _tmpRequests;
136 : Vector<AssetMultiRequest> _tmpMultiRequest;
137 : };
138 :
139 : }
140 :
141 : #endif /* XENOLITH_RESOURCES_ASSETS_XLASSETLIBRARY_H_ */
|