LCOV - code coverage report
Current view: top level - xenolith/scene/nodes - XLScene.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 125 136 91.9 %
Date: 2024-05-12 00:16:13 Functions: 24 26 92.3 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2021 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 "XLScene.h"
      25             : 
      26             : #include "XLFrameInfo.h"
      27             : #include "XLInputDispatcher.h"
      28             : #include "XLDirector.h"
      29             : #include "XLSceneContent.h"
      30             : #include "XLCoreFrameRequest.h"
      31             : 
      32             : namespace STAPPLER_VERSIONIZED stappler::xenolith {
      33             : 
      34           0 : static void Scene_findUnresolvedInputs(const memory::vector<core::AttachmentData *> &queue,
      35             :                 const memory::set<const core::AttachmentData *> &resolved) {
      36           0 :         for (auto &it : queue) {
      37           0 :                 auto iit = resolved.find(it);
      38           0 :                 if (iit == resolved.end()) {
      39           0 :                         log::warn("Scene", "No input defined for attachment: ", it->key);
      40             :                 }
      41             :         }
      42           0 : }
      43             : 
      44          21 : Scene::~Scene() {
      45          21 :         _queue = nullptr;
      46          21 : }
      47             : 
      48          21 : bool Scene::init(Queue::Builder &&builder, const core::FrameContraints &constraints) {
      49          21 :         if (!Node::init()) {
      50           0 :                 return false;
      51             :         }
      52             : 
      53          21 :         setLocalZOrder(ZOrderTransparent);
      54             : 
      55          21 :         _queue = makeQueue(move(builder));
      56             : 
      57          21 :         setFrameConstraints(_constraints);
      58             : 
      59          21 :         return true;
      60             : }
      61             : 
      62        9538 : void Scene::renderRequest(const Rc<FrameRequest> &req) {
      63        9538 :         if (!_director) {
      64           0 :                 return;
      65             :         }
      66             : 
      67        9538 :         Size2 scaledExtent(_constraints.extent.width / _constraints.density, _constraints.extent.height / _constraints.density);
      68             : 
      69        9538 :         FrameInfo info;
      70        9538 :         info.request = req;
      71        9538 :         info.pool = req->getPool();
      72             : 
      73        9538 :         render(info);
      74             : 
      75        9538 :         if (info.resolvedInputs.size() != _queue->getInputAttachments().size()) {
      76           0 :                 Scene_findUnresolvedInputs(_queue->getInputAttachments(), info.resolvedInputs);
      77             :         }
      78        9538 : }
      79             : 
      80        9538 : void Scene::render(FrameInfo &info) {
      81        9538 :         info.director = _director;
      82        9538 :         info.scene = this;
      83        9538 :         info.zPath.reserve(8);
      84             : 
      85        9538 :         info.viewProjectionStack.reserve(2);
      86        9538 :         info.viewProjectionStack.push_back(_director->getGeneralProjection());
      87             : 
      88        9538 :         info.modelTransformStack.reserve(8);
      89        9538 :         info.modelTransformStack.push_back(Mat4::IDENTITY);
      90             : 
      91        9538 :         info.depthStack.reserve(4);
      92        9538 :         info.depthStack.push_back(0.0f);
      93             : 
      94        9538 :         auto eventDispatcher = _director->getInputDispatcher();
      95             : 
      96        9538 :         info.input = eventDispatcher->acquireNewStorage();
      97             : 
      98        9538 :         visitGeometry(info, NodeFlags::None);
      99        9538 :         visitDraw(info, NodeFlags::None);
     100             : 
     101        9538 :         eventDispatcher->commitStorage(move(info.input));
     102        9538 : }
     103             : 
     104          21 : void Scene::onEnter(Scene *scene) {
     105          21 :         Node::onEnter(scene);
     106          21 : }
     107             : 
     108          21 : void Scene::onExit() {
     109          21 :         Node::onExit();
     110          21 : }
     111             : 
     112          21 : void Scene::onContentSizeDirty() {
     113          21 :         Node::onContentSizeDirty();
     114             : 
     115          21 :         setAnchorPoint(Anchor::Middle);
     116          21 :         setPosition(Vec2((_contentSize * _constraints.density) / 2.0f));
     117             : 
     118          21 :         updateContentNode(_content);
     119             : 
     120             : #if DEBUG
     121          21 :         log::info("Scene", "ContentSize: ", _contentSize, " density: ", _constraints.density);
     122             : #endif
     123          21 : }
     124             : 
     125          21 : void Scene::setContent(SceneContent *content) {
     126          21 :         if (_content) {
     127           0 :                 _content->removeFromParent(true);
     128             :         }
     129          21 :         _content = nullptr;
     130          21 :         if (content) {
     131          21 :                 _content = addChild(content);
     132          21 :                 updateContentNode(_content);
     133             :         }
     134          21 : }
     135             : 
     136          21 : void Scene::onPresented(Director *dir) {
     137          21 :         _director = dir;
     138          21 :         if (getContentSize() == Size2::ZERO) {
     139           0 :                 setContentSize(_constraints.getScreenSize() / _constraints.density);
     140             :         }
     141             : 
     142          21 :         if (auto res = _queue->getInternalResource()) {
     143          21 :                 dir->getResourceCache()->addResource(res);
     144          21 :         }
     145             : 
     146          21 :         onEnter(this);
     147          21 : }
     148             : 
     149          21 : void Scene::onFinished(Director *dir) {
     150          21 :         onExit();
     151             : 
     152          21 :         if (_director == dir) {
     153          21 :                 if (auto res = _queue->getInternalResource()) {
     154          21 :                         auto cache = dir->getResourceCache();
     155          21 :                         if (cache) {
     156          21 :                                 cache->removeResource(res->getName());
     157             :                         }
     158          42 :                 }
     159             : 
     160          21 :                 _director = nullptr;
     161             :         }
     162          21 : }
     163             : 
     164        9538 : void Scene::onFrameStarted(FrameRequest &req) {
     165        9538 :         req.setSceneId(retain());
     166        9538 : }
     167             : 
     168        9538 : void Scene::onFrameEnded(FrameRequest &req) {
     169        9538 :         release(req.getSceneId());
     170        9538 : }
     171             : 
     172        9538 : void Scene::onFrameAttached(const FrameHandle *frame) {
     173             : 
     174        9538 : }
     175             : 
     176        9538 : void Scene::onFrameDetached(const FrameHandle *frame) {
     177             : 
     178        9538 : }
     179             : 
     180         210 : void Scene::setFrameConstraints(const core::FrameContraints &constraints) {
     181         210 :         if (_constraints != constraints) {
     182         189 :                 auto size = constraints.getScreenSize();
     183             : 
     184         189 :                 _constraints = constraints;
     185             : 
     186         189 :                 setContentSize(size / _constraints.density);
     187         189 :                 setScale(_constraints.density);
     188         189 :                 _contentSizeDirty = true;
     189             : 
     190         189 :                 setPosition(Vec2((_contentSize * _constraints.density) / 2.0f));
     191             : 
     192         189 :                 updateContentNode(_content);
     193             :         }
     194         210 : }
     195             : 
     196        3329 : const Size2& Scene::getContentSize() const {
     197        3329 :         return _content ? _content->getContentSize() : _contentSize;
     198             : }
     199             : 
     200          42 : void Scene::setClipContent(bool value) {
     201          42 :         if (_content) {
     202          42 :                 if (isClipContent() != value) {
     203          42 :                         if (value) {
     204          21 :                                 _content->enableScissor();
     205             :                         } else {
     206          21 :                                 _content->disableScissor();
     207             :                         }
     208             :                 }
     209             :         }
     210          42 : }
     211             : 
     212          84 : bool Scene::isClipContent() const {
     213          84 :         return _content ? _content->isScissorEnabled() : false;
     214             : }
     215             : 
     216          21 : auto Scene::makeQueue(Queue::Builder &&builder) -> Rc<Queue> {
     217          21 :         builder.setBeginCallback([this] (FrameRequest &frame) {
     218        9538 :                 onFrameStarted(frame);
     219        9538 :         });
     220          21 :         builder.setEndCallback([this] (FrameRequest &frame) {
     221        9538 :                 onFrameEnded(frame);
     222        9538 :         });
     223          21 :         builder.setAttachCallback([this] (const FrameHandle *frame) {
     224        9538 :                 onFrameAttached(frame);
     225        9538 :         });
     226          21 :         builder.setDetachCallback([this] (const FrameHandle *frame) {
     227        9538 :                 onFrameDetached(frame);
     228        9538 :         });
     229             : 
     230          21 :         return Rc<Queue>::create(move(builder));
     231             : }
     232             : 
     233         231 : void Scene::updateContentNode(SceneContent *content) {
     234         231 :         if (content) {
     235         231 :                 auto padding = _constraints.contentPadding / _constraints.density;
     236             : 
     237         231 :                 content->setPosition(Vec2(padding.left, padding.bottom));
     238         231 :                 content->setContentSize(Size2(_contentSize.width - padding.horizontal(), _contentSize.height - padding.vertical()));
     239         231 :                 content->setAnchorPoint(Anchor::BottomLeft);
     240         231 :                 content->setDecorationPadding(padding);
     241             :         }
     242         231 : }
     243             : 
     244             : }

Generated by: LCOV version 1.14