LCOV - code coverage report
Current view: top level - xenolith/application - XLTemporaryResource.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 77 113 68.1 %
Date: 2024-05-12 00:16:13 Functions: 12 15 80.0 %

          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             : #include "XLTemporaryResource.h"
      24             : #include "XLMeshIndex.h"
      25             : #include "XLTexture.h"
      26             : #include "XLCorePlatform.h"
      27             : #include "XLCoreObject.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler::xenolith {
      30             : 
      31             : XL_DECLARE_EVENT_CLASS(TemporaryResource, onLoaded);
      32             : 
      33          30 : TemporaryResource::~TemporaryResource() {
      34          15 :         if (_resource) {
      35           0 :                 _resource->clear();
      36           0 :                 _resource = nullptr;
      37             :         }
      38          30 : }
      39             : 
      40          15 : bool TemporaryResource::init(Rc<core::Resource> &&res, TimeInterval timeout, TemporaryResourceFlags flags) {
      41          15 :         _atime = platform::clock(core::ClockType::Monotonic);
      42          15 :         _timeout = timeout;
      43          15 :         _resource = move(res);
      44          15 :         _name = _resource->getName().str<Interface>();
      45             : 
      46          15 :         if ((flags & TemporaryResourceFlags::Loaded) != TemporaryResourceFlags::None) {
      47           0 :                 setLoaded(true);
      48             :         }
      49             : 
      50          15 :         if ((flags & TemporaryResourceFlags::RemoveOnClear) != TemporaryResourceFlags::None) {
      51           0 :                 _removeOnClear = true;
      52             :         }
      53             : 
      54          15 :         return true;
      55             : }
      56             : 
      57          15 : void TemporaryResource::invalidate() {
      58          15 :         for (auto &it : _textures) {
      59           0 :                 it.second->invalidate();
      60             :         }
      61          15 :         for (auto &it : _meshIndexes) {
      62           0 :                 it.second->invalidate();
      63             :         }
      64             : 
      65          15 :         _owners.clear();
      66          15 :         _resource = nullptr;
      67          15 : }
      68             : 
      69           6 : Rc<Texture> TemporaryResource::acquireTexture(StringView str) {
      70           6 :         if (auto v = _resource->getImage(str)) {
      71           6 :                 auto it = _textures.find(v);
      72           6 :                 if (it == _textures.end()) {
      73           0 :                         it = _textures.emplace(v, Rc<Texture>::create(v, this)).first;
      74             :                 }
      75           6 :                 return it->second;
      76             :         }
      77           0 :         return nullptr;
      78             : }
      79             : 
      80           0 : Rc<MeshIndex> TemporaryResource::acquireMeshIndex(StringView str) {
      81           0 :         if (auto v = _resource->getBuffer(str)) {
      82           0 :                 auto it = _meshIndexes.find(v);
      83           0 :                 if (it == _meshIndexes.end()) {
      84           0 :                         it = _meshIndexes.emplace(v, Rc<MeshIndex>::create(v, this)).first;
      85             :                 }
      86           0 :                 return it->second;
      87             :         }
      88           0 :         return nullptr;
      89             : }
      90             : 
      91          30 : void TemporaryResource::setLoaded(bool val) {
      92          30 :         if (val) {
      93          15 :                 _requested = true;
      94          15 :                 for (auto &it : _callbacks) {
      95           0 :                         it.second(true);
      96           0 :                         -- _users;
      97             :                 }
      98          15 :                 _callbacks.clear();
      99          15 :                 if (_loaded != val) {
     100          15 :                         _loaded = val;
     101          15 :                         onLoaded(this, _loaded);
     102             :                 }
     103             :         } else {
     104          15 :                 _loaded = false;
     105          15 :                 _requested = false;
     106          15 :                 _resource->clear();
     107          15 :                 onLoaded(this, _loaded);
     108             :         }
     109          30 :         _atime = platform::clock(core::ClockType::Monotonic);
     110          30 : }
     111             : 
     112          15 : void TemporaryResource::setRequested(bool val) {
     113          15 :         _requested = val;
     114          15 : }
     115             : 
     116           0 : void TemporaryResource::setTimeout(TimeInterval ival) {
     117           0 :         _timeout = ival;
     118           0 : }
     119             : 
     120           0 : bool TemporaryResource::load(Ref *ref, Function<void(bool)> &&cb) {
     121           0 :         _atime = platform::clock(core::ClockType::Monotonic);
     122           0 :         if (_loaded) {
     123           0 :                 if (cb) {
     124           0 :                         cb(false);
     125             :                 }
     126           0 :                 return false;
     127             :         } else {
     128           0 :                 _callbacks.emplace_back(pair(ref, move(cb)));
     129           0 :                 ++ _users;
     130           0 :                 return true;
     131             :         }
     132             : }
     133             : 
     134          21 : void TemporaryResource::onEnter(ResourceOwner *owner, ResourceObject *res) {
     135          21 :         _owners.emplace(owner);
     136          21 :         _atime = platform::clock(core::ClockType::Monotonic);
     137             : 
     138          21 :         if (res->getType() == ResourceType::Texture) {
     139          21 :                 auto tex = (Texture *)res;
     140          21 :                 auto v = tex->getImageData();
     141          21 :                 auto it = _textures.find(v);
     142          21 :                 if (it == _textures.end()) {
     143          15 :                         _textures.emplace(v, tex);
     144             :                 }
     145           0 :         } else if (res->getType() == ResourceType::MeshIndex) {
     146           0 :                 auto mesh = (MeshIndex *)res;
     147           0 :                 auto v = mesh->getVertexData();
     148           0 :                 auto it = _meshIndexes.find(v);
     149           0 :                 if (it == _meshIndexes.end()) {
     150           0 :                         _meshIndexes.emplace(v, mesh);
     151             :                 }
     152             :         }
     153             : 
     154          21 :         ++ _users;
     155          21 : }
     156             : 
     157          21 : void TemporaryResource::onExit(ResourceOwner *, ResourceObject *) {
     158          21 :         _atime = platform::clock(core::ClockType::Monotonic);
     159          21 :         -- _users;
     160          21 : }
     161             : 
     162          15 : bool TemporaryResource::clear() {
     163          15 :         Vector<uint64_t> ids;
     164          30 :         for (auto &it : _textures) {
     165          15 :                 if (it.first->image) {
     166          15 :                         emplace_ordered(ids, it.first->image->getIndex());
     167             :                 }
     168             :         }
     169             : 
     170          15 :         if (!ids.empty()) {
     171          30 :                 for (auto &it : _owners) {
     172          15 :                         it->revokeImages(ids);
     173             :                 }
     174             :         }
     175          15 :         _textures.clear();
     176          15 :         _meshIndexes.clear();
     177          15 :         _owners.clear();
     178             : 
     179          15 :         setLoaded(false);
     180          15 :         return _removeOnClear;
     181          15 : }
     182             : 
     183          30 : StringView TemporaryResource::getName() const {
     184          30 :         return _resource->getName();
     185             : }
     186             : 
     187        1110 : bool TemporaryResource::isDeprecated(const UpdateTime &time) const {
     188        1110 :         if (_users > 0 || !_loaded) {
     189        1005 :                 return false;
     190             :         }
     191             : 
     192         105 :         if (_timeout == TimeInterval()) {
     193           0 :                 return true;
     194         105 :         } else if (_atime + _timeout.toMicroseconds() < time.global) {
     195          15 :                 return true;
     196             :         }
     197             : 
     198          90 :         return false;
     199             : }
     200             : 
     201             : }

Generated by: LCOV version 1.14