Completed
Push — master ( 431b60...331673 )
by Marko
10s
created

Scene::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
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
33
final class Scene
34
{
35
    /* All scenes can use primitives */
36
    use Primitives;
37
    
38
    /**
39
     * Name with what you can retrieve this scene while working with multiple scenes
40
     *
41
     * @var string $name
42
     */
43
    private $keyword;
44
    
45
    /**
46
     * Is scene prepared for rendering
47
     *
48
     * @var bool
49
     */
50
    private $prepared;
51
    
52
    /**
53
     * Assets
54
     * 
55
     * @var \AframeVR\Core\Assets
56
     */
57
    protected $assets;
58
    
59
    /**
60
     * Aframe Document Object Model
61
     *
62
     * @var \AframeVR\Core\DOM\AframeDOMDocument
63
     */
64
    protected $aframeDomObj;
65
    
66
    /**
67
     * A-Frame scene entities
68
     *
69
     * @var array $entities
70
     */
71
    protected $entities = array();
72
73
    /**
74
     * Scene components
75
     * 
76
     * @var array $components
77
     */
78
    protected $components = array();
79
    
80
    /**
81
     * Scene constructor
82
     *
83
     * @param string $keyword            
84
     * @param Config $config            
85
     */
86 98
    public function __construct(string $keyword, Config $config)
87
    {
88 98
        $this->keyword      = $keyword;
89 98
        $this->aframeDomObj = new AframeDOMDocument($config);
90
        /* Initialize assests manager */
91 98
        $this->asset();
92 98
    }
93
94
    /**
95
     * Aframe Document Object Model
96
     *
97
     * @api
98
     *
99
     * @return \AframeVR\Core\DOM\AframeDOMDocument
100
     */
101 8
    public function dom()
102
    {
103 8
        return $this->aframeDomObj;
104
    }
105
106
    /**
107
     * Entity
108
     *
109
     * @api
110
     *
111
     * @param string $id            
112
     * @return \AframeVR\Core\Entity
113
     */
114 47
    public function entity(string $id = 'untitled'): Entity
115
    {
116 47
        return $this->entities[$id] ?? $this->entities[$id] = new Entity($id);
117
    }
118
119
    /**
120
     * Assets
121
     *
122
     * @api
123
     *
124
     * @return \AframeVR\Core\Assets
125
     */
126 98
    public function asset(): Assets
127
    {
128 98
        return $this->assets ?? $this->assets = new Assets();
129
    }
130
131
    /**
132
     * Render the A-Frame scene and return the HTML
133
     *
134
     * @api
135
     *
136
     * @param bool $only_scene            
137
     * @return string
138
     */
139 9
    public function save($only_scene = false, string $file = null): string
140
    {
141 9
        $this->prepare();
142 9
        $html = ! $only_scene ? $this->aframeDomObj->render() : $this->aframeDomObj->renderSceneOnly();
143 9
        if (! empty($file) && is_writable(dirname($file))) {
144 1
            file_put_contents($file, $html);
145
        }
146
        
147 9
        return $html;
148
    }
149
150
    /**
151
     * Render the A-Frame scene and passthru HTML
152
     *
153
     * @api
154
     *
155
     * @param bool $only_scene            
156
     * @return void
157
     */
158 1
    public function render($only_scene = false)
159
    {
160 1
        print $this->save($only_scene);
161 1
    }
162
163
    /**
164
     * Alias of AframeDOMDocument::setTitle(string)
165
     *
166
     * Set <title> tag
167
     * $this->dom()->setTitle(string);
168
     *
169
     * @api
170
     *
171
     * @param string $title            
172
     */
173 7
    public function title(string $title)
174
    {
175 7
        $this->dom()->setTitle($title);
176 7
    }
177
178
    /**
179
     * Alias of AframeDOMDocument::setDescription(string)
180
     *
181
     * Set <meta name="description"> tag
182
     * $this->dom()->setDescription(string);
183
     *
184
     * @api
185
     *
186
     * @param string $description            
187
     */
188 7
    public function description(string $description)
189
    {
190 7
        $this->dom()->setDescription($description);
191 7
    }
192
193
    /**
194
     * Get scenes keyword
195
     *
196
     * @return string
197
     */
198 1
    public function getKeyword()
199
    {
200 1
        return $this->keyword;
201
    }
202
203
    /**
204
     * Load component for this entity
205
     *
206
     * @param string $component_name
207
     * @throws \AframeVR\Core\Exceptions\BadComponentCallException
208
     * @return object|null
209
     */
210 2 View Code Duplication
    public function component(string $component_name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
211
    {
212 2
        if (! array_key_exists($component_name, $this->components)) {
213 2
            $component = sprintf('\AframeVR\Core\Components\ascene\%s\%sComponent', ucfirst($component_name),
214
                ucfirst($component_name));
215 2
            if (class_exists($component)) {
216 1
                $this->components[$component_name] = new $component();
217
            } else {
218 1
                throw new BadComponentCallException($component_name);
219
            }
220
        }
221
    
222 1
        return $this->components[$component_name] ?? null;
223
    }
224
    
225
    /**
226
     * Handle scene components
227
     *
228
     * Since we might need to customize these to have
229
     * custom components loaded as $this->methosd aswell therefore
230
     * we have these placeholder magic methods here
231
     *
232
     * @param string $component_name
233
     * @param array $args
234
     */
235 2 View Code Duplication
    public function __call(string $component_name, array $args)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
236
    {
237 2
        if (! method_exists($this, $component_name)) {
238 2
            $this->{$component_name} = Closure::bind(
239 2
                function () use ($component_name) {
240 2
                    return $this->component($component_name);
241 2
                }, $this, get_class());
242
        }
243
    
244 2
        return call_user_func($this->{$component_name}, $args);
245
    }
246
    
247
    
248
    /**
249
     * Add everyting to DOM
250
     *
251
     * @return void
252
     */
253 9
    protected function prepare()
254
    {
255 9
        if ($this->prepared)
256 1
            return;
257
            
258
            /* Append all assets */
259 9
        $assets = $this->assets->getAssets();
260 9
        (! $assets) ?: $this->aframeDomObj->appendAssets($assets);
261
        
262
        /* Append all primitives */
263 9
        $this->preparePrimitives();
264
        
265
        /* Append all entities */
266 9
        $this->aframeDomObj->appendEntities($this->entities);
267 9
        $this->aframeDomObj->appendSceneComponents($this->components);
268 9
        $this->prepared = true;
269 9
    }
270
}
271