Completed
Push — master ( be4ea7...74ddb0 )
by Marko
8s
created

Scene::dom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/** @formatter:off
3
 * ******************************************************************
4
 * Created by   Marko Kungla on Jun 20, 2016 - 9:01:22 PM
5
 * Contact      [email protected]
6
 * @copyright   2016 Marko Kungla - https://github.com/mkungla
7
 * @license     The MIT License (MIT)
8
 * 
9
 * @category       AframeVR
10
 * @package        aframe-php
11
 * 
12
 * Lang         PHP (php version >= 7)
13
 * Encoding     UTF-8
14
 * File         Scene.php
15
 * Code format  PSR-2 and 12
16
 * @link        https://github.com/mkungla/aframe-php
17
 * @issues      https://github.com/mkungla/aframe-php/issues
18
 * ********************************************************************
19
 * Contributors:
20
 * @author Marko Kungla <[email protected]>
21
 * ********************************************************************
22
 * Comments:
23
 * @formatter:on */
24
namespace AframeVR\Core;
25
26
use \AframeVR\Extras\Primitives;
27
use \AframeVR\Core\Entity;
28
use \AframeVR\Core\DOM\AframeDOMDocument;
29
use \AframeVR\Core\Assets;
30
use \Closure;
31
use \AframeVR\Core\Exceptions\BadComponentCallException;
32
use \AframeVR\Core\Helpers\EntityChildrenFactory;
33
34
final class Scene
35
{
36
    /* All scenes can use primitives */
37
    use Primitives;
38
    
39
    /**
40
     * Name with what you can retrieve this scene while working with multiple scenes
41
     *
42
     * @var string $name
43
     */
44
    private $keyword;
45
    
46
    /**
47
     * Is scene prepared for rendering
48
     *
49
     * @var bool
50
     */
51
    private $prepared;
52
    
53
    /**
54
     * Assets
55
     *
56
     * @var \AframeVR\Core\Assets
57
     */
58
    protected $assets;
59
    
60
    /**
61
     * Aframe Document Object Model
62
     *
63
     * @var \AframeVR\Core\DOM\AframeDOMDocument
64
     */
65
    protected $aframeDomObj;
66
    
67
    /**
68
     * Scene components
69
     *
70
     * @var array $components
71
     */
72
    protected $components = array();
73
74
    /**
75
     * Children Factory
76
     *
77
     * @var \AframeVR\Core\Helpers\EntityChildrenFactory
78
     */
79
    protected $childrenFactory;
80
    
81
    /**
82
     * Scene constructor
83
     *
84
     * @param string $keyword            
85
     * @param Config $config            
86
     */
87 98
    public function __construct(string $keyword, Config $config)
88
    {
89 98
        $this->keyword         = $keyword;
90 98
        $this->aframeDomObj    = new AframeDOMDocument($config);
91 98
        $this->childrenFactory = new EntityChildrenFactory();
92
        /* Initialize assests manager */
93 98
        $this->asset();
94 98
    }
95
96
    /**
97
     * Aframe Document Object Model
98
     *
99
     * @api
100
     *
101
     * @return \AframeVR\Core\DOM\AframeDOMDocument
102
     */
103 2
    public function dom()
104
    {
105 2
        return $this->aframeDomObj;
106
    }
107
    
108
    /**
109
     * Assets
110
     *
111
     * @api
112
     *
113
     * @return \AframeVR\Core\Assets
114
     */
115 98
    public function asset(): Assets
116
    {
117 98
        return $this->assets ?? $this->assets = new Assets();
118
    }
119
120
    /**
121
     * Child entity / primitive
122
     *
123
     * @return \AframeVR\Core\Helpers\EntityChildrenFactory
124
     */
125 77
    public function child(): EntityChildrenFactory
126
    {
127 77
        return $this->childrenFactory;
128
    }
129
    
130
    /**
131
     * Render the A-Frame scene and return the HTML
132
     *
133
     * @api
134
     *
135
     * @param bool $only_scene            
136
     * @return string
137
     */
138 19
    public function save($only_scene = false, string $file = null): string
139
    {
140 19
        $this->prepare();
141 19
        $html = ! $only_scene ? $this->aframeDomObj->render() : $this->aframeDomObj->renderSceneOnly();
142 19
        if (! empty($file) && is_writable(dirname($file))) {
143 1
            file_put_contents($file, $html);
144
        }
145
        
146 19
        return $html;
147
    }
148
149
    /**
150
     * Render the A-Frame scene and passthru HTML
151
     *
152
     * @api
153
     *
154
     * @param bool $only_scene            
155
     * @return void
156
     */
157 1
    public function render($only_scene = false)
158
    {
159 1
        print $this->save($only_scene);
160 1
    }
161
162
    /**
163
     * Alias of AframeDOMDocument::setTitle(string)
164
     *
165
     * Set <title> tag
166
     * $this->dom()->setTitle(string);
167
     *
168
     * @api
169
     *
170
     * @param string $title            
171
     */
172 1
    public function title(string $title)
173
    {
174 1
        $this->dom()->setTitle($title);
175 1
    }
176
177
    /**
178
     * Alias of AframeDOMDocument::setDescription(string)
179
     *
180
     * Set <meta name="description"> tag
181
     * $this->dom()->setDescription(string);
182
     *
183
     * @api
184
     *
185
     * @param string $description            
186
     */
187 1
    public function description(string $description)
188
    {
189 1
        $this->dom()->setDescription($description);
190 1
    }
191
192
    /**
193
     * Get scenes keyword
194
     *
195
     * @return string
196
     */
197 1
    public function getKeyword()
198
    {
199 1
        return $this->keyword;
200
    }
201
202
    /**
203
     * Load component for this entity
204
     *
205
     * @param string $component_name            
206
     * @throws \AframeVR\Core\Exceptions\BadComponentCallException
207
     * @return object|null
208
     */
209 2
    public function component(string $component_name)
210
    {
211 2
        if (! array_key_exists($component_name, $this->components)) {
212 2
            $component = sprintf('\AframeVR\Core\Components\ascene\%s\%sComponent', ucfirst($component_name), 
213
                ucfirst($component_name));
214 2
            if (class_exists($component)) {
215 1
                $this->components[$component_name] = new $component();
216
            } else {
217 1
                throw new BadComponentCallException($component_name);
218
            }
219
        }
220
        
221 1
        return $this->components[$component_name] ?? null;
222
    }
223
224
    /**
225
     * Map calls to scene entities and components
226
     *
227
     * Since we might need to customize these to have
228
     * custom components loaded as $this->methosd aswell therefore
229
     * we have these placeholder magic methods here
230
     *
231
     * @param string $method            
232
     * @param array $args            
233
     * @throws BadShaderCallException
234
     * @return Entity|\AframeVR\Interfaces\ComponentInterface
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
235
     */
236 79
    public function __call(string $method, array $args)
237
    {
238 79
        $id        = $args[0] ?? 0;
239 79
        $primitive = sprintf('\AframeVR\Extras\Primitives\%s', ucfirst($method));
240
        
241 79
        if ($method === 'entity' || class_exists($primitive)) {
242 77
            return $this->child()->getEntity($method, $id);
243
        } else {
244 2
            return $this->component($method);
245
        }
246
    }
247
248
    /**
249
     * Add everyting to DOM
250
     *
251
     * @return void
252
     */
253 19
    protected function prepare()
254
    {
255 19
        if ($this->prepared)
256 1
            return;
257
            
258
            /* Append all assets */
259 19
        $assets = $this->assets->getAssets();
260 19
        (! $assets) ?: $this->aframeDomObj->appendAssets($assets);
261
        /* Append all primitives */
262 19
        $this->preparePrimitives();
263
        
264
        /* Append all entities */
265 19
        $this->aframeDomObj->appendEntities($this->childrenFactory->getChildren());
266 19
        $this->aframeDomObj->appendSceneComponents($this->components);
267 19
        $this->prepared = true;
268 19
    }
269
}
270