Completed
Push — master ( 95af13...697c38 )
by Marko
8s
created

Entity::appendChildren()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 10
cts 10
cp 1
rs 9.2
cc 4
eloc 9
nc 5
nop 2
crap 4
1
<?php
2
/** @formatter:off
3
 * ******************************************************************
4
 * Created by   Marko Kungla on Jun 20, 2016 - 9:11:10 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         Entity.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\Core\Exceptions\BadComponentCallException;
27
use \AframeVR\Interfaces\{
28
    ComponentInterface,
29
    EntityInterface,
30
    AnimationInterface
31
};
32
use \AframeVR\Core\Animation;
33
use \DOMElement;
34
use \Closure;
35
36
class Entity implements EntityInterface
37
{
38
    /**
39
     * Array of used components
40
     * 
41
     * @var array
42
     */
43
    protected $components = array();
44
45
    /**
46
     * Array of used animations
47
     * 
48
     * @var array
49
     */
50
    protected $animations = array();
51
52
    /**
53
     * Child entities
54
     *
55
     * @var array
56
     */
57
    protected $entities = array();
58
    
59 64
    public function __construct()
60
    {
61
        /* Components which All entities inherently have */
62 64
        $this->component('Position');
63 64
        $this->component('Rotation');
64 64
        $this->component('Scale');
65
        
66
        /* Extending entity components and init */
67 64
        $this->init();
68
        
69
        /* Extending entity defaults */
70 64
        $this->defaults();
71 64
    }
72
73 37
    public function init()
74 37
    {}
75
76 37
    public function defaults()
77 37
    {}
78
79
    /**
80
     * Child entity
81
     *
82
     * @param string $name
83
     * @return Entity
84
     */
85 6
    public function entity(string $name = 'untitled'): Entity
86
    {
87 6
        return $this->entities[$name] ?? $this->entities[$name] = new Entity();
88
    }
89
    
90
    /**
91
     * Position component
92
     *
93
     * All entities inherently have the position component.
94
     *
95
     * @param int|float $x_axis            
96
     * @param int|float $y_axis            
97
     * @param int|float $z_axis            
98
     * @return \AframeVR\Core\Entity
99
     */
100 14
    public function position(float $x_axis = 0, float $y_axis = 0, float $z_axis = 0): Entity
101
    {
102 14
        $this->component('Position')->positionX($x_axis);
103 14
        $this->component('Position')->positionY($y_axis);
104 14
        $this->component('Position')->positionZ($z_axis);
105 14
        return $this;
106
    }
107
108
    /**
109
     * Rotation component
110
     *
111
     * All entities inherently have the rotation component.
112
     *
113
     * @param int|float $roll            
114
     * @param int|float $pitch            
115
     * @param int|float $yaw            
116
     * @return \AframeVR\Core\Entity
117
     */
118 14
    public function rotation(float $roll = 0, float $pitch = 0, float $yaw = 0): Entity
119
    {
120 14
        $this->component('Rotation')->roll($roll);
121 14
        $this->component('Rotation')->pitch($pitch);
122 14
        $this->component('Rotation')->yaw($yaw);
123 14
        return $this;
124
    }
125
126
    /**
127
     * Scale component
128
     *
129
     * All entities inherently have the scale component.
130
     *
131
     * @param int|float $scale_x            
132
     * @param int|float $scale_y            
133
     * @param int|float $scale_z            
134
     * @return \AframeVR\Core\Entity
135
     */
136 9
    public function scale(float $scale_x = 1, float $scale_y = 1, float $scale_z = 1): Entity
137
    {
138 9
        $this->component('Scale')->scaleX($scale_x);
139 9
        $this->component('Scale')->scaleY($scale_y);
140 9
        $this->component('Scale')->scaleZ($scale_z);
141 9
        return $this;
142
    }
143
144
    /**
145
     * Animations
146
     *
147
     * @param string $name            
148
     * @return \AframeVR\Interfaces\AnimationInterface
149
     */
150 1
    public function animation(string $name = 'untitled'): AnimationInterface
151
    {
152 1
        return $this->animations[$name] ?? $this->animations[$name] = new Animation();
153
    }
154
155
    /**
156
     * Load component for this entity
157
     *
158
     * @param string $component_name            
159
     * @throws \AframeVR\Core\Exceptions\BadComponentCallException
160
     * @return object|null
161
     */
162 64 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...
163
    {
164 64
        if (! array_key_exists($component_name, $this->components)) {
165 64
            $component = sprintf(
166 64
                '\AframeVR\Core\Components\%s\%sComponent',
167
                ucfirst($component_name),
168
                ucfirst($component_name)
169
            );
170 64
            if (class_exists($component)) {
171 64
                $this->components[$component_name] = new $component();
172
            } else {
173 1
                throw new BadComponentCallException($component_name);
174
            }
175
        }
176
        
177 64
        return $this->components[$component_name] ?? null;
178
    }
179
180
    /**
181
     * Handle entity components
182
     *
183
     * Since we might need to customize these to have
184
     * custom components loaded as $this->methosd aswell therefore
185
     * we have these placeholder magic methods here
186
     *
187
     * @param string $component_name            
188
     * @param array $args            
189
     */
190 12 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...
191
    {
192 12
        if (! method_exists($this, $component_name)) {
193 12
            $this->{$component_name} = Closure::bind(function () use ($component_name) {
194 12
                return $this->component($component_name);
195 12
            }, $this, get_class());
196
        }
197
        
198 12
        return call_user_func($this->{$component_name}, $args);
199
    }
200
201
    /**
202
     * Create and add DOM element of the entity
203
     *
204
     * @param \DOMDocument $aframe_dom            
205
     * @return \DOMElement
206
     */
207 4
    public function domElement(\DOMDocument &$aframe_dom): DOMElement
208
    {
209 4
        $a_entity = $aframe_dom->createElement('a-entity');
210 4
        foreach ($this->components as $component) {
211
            /*
212
             * Check does component has any attributes to add to DOM element.
213
             * default attributes most of cases are ommited so we might not have any attributes to add
214
             */
215 4
            if ($component->hasDOMAttributes())
216 4
                $a_entity->setAttributeNode($component->getDOMAttr());
217
        }
218
        
219 4
        $this->appendChildren($aframe_dom, $a_entity);
220
        
221 4
        return $a_entity;
222
    }
223
    
224 4
    private function appendChildren(\DOMDocument &$aframe_dom, \DOMElement &$a_entity)
225
    {
226 4
        foreach($this->entities as $entity) {
227 2
            if ($aframe_dom->formatOutput) {
228 2
                $com = $aframe_dom->createComment("\n\t");
229 2
                $a_entity->appendChild($com);
230
            }
231 2
            $a_entity->appendChild($entity->domElement($aframe_dom));
232 2
            if ($aframe_dom->formatOutput) {
233 2
                $com = $aframe_dom->createComment("\n");
234 2
                $a_entity->appendChild($com);
235
            }
236
        }
237 4
    }
238
}
239