Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #include "XLCoreDynamicImage.h"
25 : #include "XLCoreMaterial.h"
26 :
27 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
28 :
29 64 : DynamicImage::~DynamicImage() { }
30 :
31 32 : bool DynamicImage::init(const Callback<bool(Builder &)> &cb) {
32 32 : Builder builder(this);
33 32 : if (cb(builder)) {
34 32 : return true;
35 : }
36 0 : return false;
37 : }
38 :
39 32 : void DynamicImage::finalize() {
40 32 : std::unique_lock<Mutex> lock(_mutex);
41 32 : _instance->userdata = nullptr;
42 32 : _instance = nullptr;
43 32 : }
44 :
45 4305 : Rc<DynamicImageInstance> DynamicImage::getInstance() {
46 4305 : std::unique_lock<Mutex> lock(_mutex);
47 8610 : return _instance;
48 4305 : }
49 :
50 812 : void DynamicImage::updateInstance(Loop &loop, const Rc<ImageObject> &obj, Rc<DataAtlas> &&atlas, Rc<Ref> &&userdata,
51 : const Vector<Rc<DependencyEvent>> &deps) {
52 812 : auto newInstance = Rc<DynamicImageInstance>::alloc();
53 812 : static_cast<ImageInfoData &>(newInstance->data) = obj->getInfo();
54 812 : newInstance->data.image = obj;
55 812 : newInstance->data.atlas = move(atlas);
56 812 : newInstance->userdata = move(userdata);
57 812 : newInstance->image = this;
58 :
59 812 : std::unique_lock<Mutex> lock(_mutex);
60 812 : if (!_instance) {
61 0 : return;
62 : }
63 :
64 812 : newInstance->gen = _instance->gen + 1;
65 812 : _instance = newInstance;
66 812 : _data.image = nullptr;
67 :
68 1624 : for (auto &it : _materialTrackers) {
69 812 : it->updateDynamicImage(loop, this, deps);
70 : }
71 812 : }
72 :
73 16 : void DynamicImage::addTracker(const MaterialAttachment *a) {
74 16 : std::unique_lock<Mutex> lock(_mutex);
75 16 : _materialTrackers.emplace(a);
76 16 : }
77 :
78 0 : void DynamicImage::removeTracker(const MaterialAttachment *a) {
79 0 : std::unique_lock<Mutex> lock(_mutex);
80 0 : _materialTrackers.erase(a);
81 0 : }
82 :
83 5490 : ImageInfo DynamicImage::getInfo() const {
84 5490 : std::unique_lock<Mutex> lock(_mutex);
85 10980 : return ImageInfo(static_cast<const ImageInfo &>(_data));
86 5490 : }
87 :
88 0 : Extent3 DynamicImage::getExtent() const {
89 0 : std::unique_lock<Mutex> lock(_mutex);
90 0 : if (_instance) {
91 0 : return _instance->data.extent;
92 : } else {
93 0 : return _data.extent;
94 : }
95 0 : }
96 :
97 32 : void DynamicImage::setImage(const Rc<ImageObject> &obj) {
98 32 : std::unique_lock<Mutex> lock(_mutex);
99 :
100 32 : _data.image = obj;
101 :
102 32 : auto newInstance = Rc<DynamicImageInstance>::alloc();
103 32 : static_cast<ImageInfoData &>(newInstance->data) = obj->getInfo();
104 32 : newInstance->data.image = obj;
105 32 : newInstance->image = this;
106 32 : newInstance->gen = 1;
107 :
108 32 : _instance = newInstance;
109 32 : }
110 :
111 32 : void DynamicImage::acquireData(const Callback<void(BytesView)> &cb) {
112 32 : if (!_data.data.empty()) {
113 0 : cb(_data.data);
114 32 : } else if (_data.stdCallback) {
115 32 : _data.stdCallback(nullptr, 0, cb);
116 0 : } else if (_data.memCallback) {
117 0 : _data.memCallback(nullptr, 0, cb);
118 : }
119 32 : }
120 :
121 0 : const ImageData * DynamicImage::Builder::setImageByRef(StringView key, ImageInfo &&info, BytesView data, Rc<DataAtlas> &&atlas) {
122 0 : static_cast<ImageInfo &>(_data->_data) = info;
123 0 : _data->_data.key = key;
124 0 : _data->_data.data = data;
125 0 : _data->_data.atlas = move(atlas);
126 0 : return &_data->_data;
127 : }
128 :
129 0 : const ImageData * DynamicImage::Builder::setImage(StringView key, ImageInfo &&info, FilePath path, Rc<DataAtlas> &&atlas) {
130 0 : String npath;
131 0 : if (filesystem::exists(path.get())) {
132 0 : npath = path.get().str<Interface>();
133 0 : } else if (!filepath::isAbsolute(path.get())) {
134 0 : npath = filesystem::currentDir<Interface>(path.get());
135 0 : if (!filesystem::exists(npath)) {
136 0 : npath.clear();
137 : }
138 : }
139 :
140 0 : if (npath.empty()) {
141 0 : log::error("Resource", "Fail to add image: ", key, ", file not found: ", path.get());
142 0 : return nullptr;
143 : }
144 :
145 0 : _data->_keyData = key.str<Interface>();
146 0 : static_cast<ImageInfo &>(_data->_data) = info;
147 0 : _data->_data.key = _data->_keyData;
148 0 : _data->_data.stdCallback = [npath, format = info.format] (uint8_t *ptr, uint64_t size, const ImageData::DataCallback &dcb) {
149 0 : Resource::loadImageFileData(ptr, size, npath, format, dcb);
150 0 : };;
151 0 : _data->_data.atlas = move(atlas);
152 0 : return &_data->_data;
153 0 : }
154 :
155 0 : const ImageData * DynamicImage::Builder::setImage(StringView key, ImageInfo &&info, BytesView data, Rc<DataAtlas> &&atlas) {
156 0 : _data->_keyData = key.str<Interface>();
157 0 : _data->_imageData = data.bytes<Interface>();
158 0 : static_cast<ImageInfo &>(_data->_data) = info;
159 0 : _data->_data.key = _data->_keyData;
160 0 : _data->_data.data = _data->_imageData;
161 0 : _data->_data.atlas = move(atlas);
162 0 : return &_data->_data;
163 : }
164 :
165 32 : const ImageData * DynamicImage::Builder::setImage(StringView key, ImageInfo &&info,
166 : Function<void(uint8_t *, uint64_t, const ImageData::DataCallback &)> &&cb, Rc<DataAtlas> &&atlas) {
167 32 : _data->_keyData = key.str<Interface>();
168 32 : static_cast<ImageInfo &>(_data->_data) = info;
169 32 : _data->_data.key = _data->_keyData;
170 32 : _data->_data.stdCallback = cb;
171 32 : _data->_data.atlas = move(atlas);
172 32 : return &_data->_data;
173 : }
174 :
175 32 : DynamicImage::Builder::Builder(DynamicImage *data) : _data(data) { }
176 :
177 : }
|