(no commit message)
[shipsimu.git] / application / ship-simu / main / class_BaseSimulator.php
1 <?php
2
3 // Ein sehr abstraktes Objekt, Abmasse, Beschreibung und Teil-Instanz werden hier gespeichert
4 class BaseSimulator extends BaseFrameworkSystem {
5         // Schiffsteilinstanz
6         private $partInstance = null;
7
8         // Abmasse (Breite/Hoehe/Laenge)
9         private $width  = 0;
10         private $height = 0;
11         private $length = 0;
12
13         // Aktuelles Schiff und Schiffsteil
14         private $currShip = null;
15         private $currPart = null;
16
17         // Faktoren zur Erweiterung der Masse. Beispielsweise soll der Maschinenraum groesser wie der Motor sein
18         private $resizeFactorArray = array(
19                 'width'  => 1,
20                 'height' => 1,
21                 'length' => 1
22         );
23
24         // Konstruktor
25         private function __construct ($class) {
26                 // Call highest constructor
27                 parent::constructor($class);
28
29                 if ((defined('DEBUG_CORE')) && (defined('DEBUG_CONSTRUCT'))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruktor erreicht.<br />\n",
30                         $this->__toString()
31                 ));
32
33                 // Set part description and class name
34                 $this->setPartDescr("Simulator-Basis-Einheit");
35
36                 // Etwas aufraeumen, dies sollte ganz zum Schluss erfolgen!
37                 $this->removeResizeFactorArray();
38                 $this->removeCurrPart();
39                 $this->removeCurrShip();
40         }
41
42         // Public constructor
43         public function constructor ($class) {
44                 // Call real constructor
45                 $this->__construct($class);
46         }
47
48         // Magic __isset method
49         private function __isset ($var) {
50                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Checking <strong>%s</strong> in class.<br />\n",
51                         $this->__toString(), $var
52                 ));
53                 return isset($this->$var);
54         }
55
56         // Magic __unset method
57         private function __unset($var) {
58                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Removing <strong>%s</strong> from class.<br />\n",
59                         $this->__toString(), $var
60                 ));
61                 unset($this->$var);
62         }
63
64         // Setter-Methode fuer Laenge
65         public function setLength ($length) {
66                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> L&auml;nge gesetzt.<br />\n",
67                         $this->__toString(),
68                         $length
69                 ));
70                 $this->length = (float) $length;
71         }
72
73         // Setter-Methode fuer Breite
74         public function setWidth ($width) {
75                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Breite gesetzt.<br />\n",
76                         $this->__toString(),
77                         $width
78                 ));
79                 $this->width = (float) $width;
80         }
81
82         // Setter-Methode fuer Hoehe
83         public function setHeight ($height) {
84                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> H&ouml;he gesetzt.<br />\n",
85                         $this->__toString(),
86                         $height
87                 ));
88                 $this->height = (float) $height;
89         }
90
91         // Getter-Methode fuer Laenge
92         public function getLength () {
93                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] L&auml;nge angefordert.<br />\n",
94                         $this->__toString()
95                 ));
96                 return $this->length;
97         }
98
99         // Getter-Methode fuer Breite
100         public function getWidth () {
101                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] L&auml;nge angefordert.<br />\n",
102                         $this->__toString()
103                 ));
104                 return $this->width;
105         }
106
107         // Getter-Methode fuer Hoehe
108         public function getHeight () {
109                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] H&ouml;he angefordert.<br />\n",
110                         $this->__toString()
111                 ));
112                 return $this->height;
113         }
114
115         // Setter-Methode fuer Teil-Instanz
116         public function setPartInstance ($struct) {
117                 $this->partInstance = (Object) $struct;
118         }
119
120         // Getter-Methode fuer Teil-Instanz
121         public function getPartInstance () {
122                 if (!isset($this->partInstance)) {
123                         return null;
124                 }
125                 return $this->partInstance;
126         }
127
128         // Remover-Methode fuer die Teil-Instanz
129         public function removePartInstance () {
130                 if ($this->getPartInstance() !== null) {
131                         // Warnung ausgeben
132                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance ist nicht null! Instanz-Attribut wird nicht entfernt.<br />\n",
133                                 $this->__toString()
134                         ));
135                 } else {
136                         // Leere Instanz kann entfernt werden
137                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance wurde entfernt.<br />\n",
138                                 $this->__toString()
139                         ));
140                         unset($this->partInstance);
141                 }
142         }
143
144         // Prueft ob all Umberechnungsfaktoren gesetzt sind
145         private function isResizeFactorValid () {
146                 return (($this->getResizeFactorElement('width')  > 1)
147                         || ($this->getResizeFactorElement('height') > 1)
148                         || ($this->getResizeFactorElement('length') > 1)
149                 );
150         }
151
152         // Baut einen Motor in das Schiff ein
153         public function addShipPartToShip (ConstructableShip $shipInstance, ConstructableShipPart $partInstance) {
154                 // Schiff/-steil merken
155                 $this->currShip = $shipInstance;
156                 $this->currPart = $partInstance;
157
158                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Maschinenraum mit Motor <strong>%s</strong> wird fuer das Schiff <strong>%s</strong> konstruiert.<br />\n",
159                         $this->__toString(),
160                         $this->currPart->getPartDescr(),
161                         $this->currShip->getShipName()
162                 ));
163
164                 // Passt ueberhaupt das Schiffsteil in's Schiff?
165                 if ($this->isShipPartSizeValid()) {
166                         // Berechnungen fuer umliegendes Objekt anpassen
167                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> vom Typ <strong>%s</strong> passt in das Schiff <strong>%s</strong> hinein.<br />\n",
168                                 $this->__toString(),
169                                 $this->currPart->getPartDescr(),
170                                 $this->currPart->__toString(),
171                                 $this->currShip->getShipName()
172                         ));
173
174                         // Muessen die Masse angepasst werden?
175                         if ($this->isResizeFactorValid()) {
176                                 // Neue Angaben berechnen (wir lassen etwas Lust fuer Kabelbaeume, Roehren, Maschinisten, etc.)
177                                 $this->newWidth  = (float) $this->currPart->getWidth()  * $this->resizeFactorArray['width'];
178                                 $this->newHeight = (float) $this->currPart->getHeight() * $this->resizeFactorArray['height'];
179                                 $this->newLength = (float) $this->currPart->getLength() * $this->resizeFactorArray['length'];
180
181                                 // Passt dies nun immer noch?
182                                 if ($this->isNewSizeValid()) {
183                                         // Das passt auch, dann Werte setzen und Motor-Instanz merken
184                                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> passt in das Schiff <strong>%s</strong> hinein.<br />\n",
185                                                 $this->__toString(),
186                                                 $this->getPartDescr(),
187                                                 $this->currShip->getShipName()
188                                         ));
189                                         $this->setWidth($this->newWidth);
190                                         $this->setHeight($this->newHeight);
191                                         $this->setLength($this->newLength);
192
193                                         // Einige Dinge entfernen...
194                                         $this->removeAllNewAttr();
195                                 } else {
196                                         // Passt nicht! Also wieder Exception werfen...
197                                         throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> vom Typ <strong>%s</strong> ist zu gross f&uuml;r das Schiff!",
198                                                 $this->currPart->__toString(),
199                                                 $this->currPart->getPartDescr(),
200                                                 $this->currPart->__toString()
201                                         ), 2);
202                                 }
203                         } elseif ($this->currPart != null) {
204                                 // Aktuelle Masse setzen
205                                 $this->setWidth($this->currPart->getWidth());
206                                 $this->setHeight($this->currPart->getHeight());
207                                 $this->setLength($this->currPart->getLength());
208                         }
209
210                         // Existiert ein Schiffsteil?
211                         if (!is_null($this->currPart)) {
212                                 // Debug-Meldung ausgeben
213                                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Schiffsteil <strong>%s</strong> gefunden.<br />\n",
214                                         $this->currPart->realClass,
215                                         $this->currPart->getPartDescr()
216                                 ));
217
218                                 // Schiffsteil-Instanz setzen
219                                 $this->setPartInstance($this->currPart);
220
221                                 // Instanzen entfernen
222                                 $this->currPart->removeCurrShip();
223                                 $this->currPart->removeCurrPart();
224                                 $this->currPart->removePartInstance();
225                                 $this->currPart->removeResizeFactorArray();
226                         }
227                 } else {
228                         // Exception werfen!
229                         throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <u>%s</u> vom Typ <u>%s</u> passt nicht in das Schiff!",
230                                 $this->currPart->realClass,
231                                 $this->currPart->getPartDescr(),
232                                 $this->currPart->__toString()
233                         ), 1);
234                 }
235
236                 // Nochmals etwas aufraeumen
237                 $this->removeResizeFactorArray();
238                 $this->removeCurrShip();
239                 $this->removeCurrPart();
240         }
241
242         // Array fuer Umrechnungstabelle entfernen
243         public function removeResizeFactorArray () {
244                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeResizeFactor erreicht.<br />\n",
245                         $this->__toString()
246                 ));
247                 unset($this->resizeFactorArray);
248         }
249
250         // Alle newXXX-Attribute entfernen
251         public function removeAllNewAttr () {
252                 unset($this->newWidth);
253                 unset($this->newHeight);
254                 unset($this->newLength);
255         }
256
257         // Aktuelle Schiff-Instanz entfernen
258         public function removeCurrShip () {
259                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrShip erreicht.<br />\n",
260                         $this->__toString()
261                 ));
262                 unset($this->currShip);
263         }
264
265         // Aktuelle Schiff-Instanz entfernen
266         public function removeCurrPart () {
267                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrPart erreicht.<br />\n",
268                         $this->__toString()
269                 ));
270                 unset($this->currPart);
271         }
272
273         // Breite entfernen
274         public function removeWidth () {
275                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Breite entfernt.<br />\n",
276                         $this->__toString()
277                 ));
278                 unset($this->width);
279         }
280
281         // Hoehe entfernen
282         public function removeHeight () {
283                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] H&ouml;he entfernt.<br />\n",
284                         $this->__toString()
285                 ));
286                 unset($this->height);
287         }
288
289         // Laenge entfernen
290         public function removeLength () {
291                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] L&auml;nge entfernt.<br />\n",
292                         $this->__toString()
293                 ));
294                 unset($this->length);
295         }
296
297         // Tiefgang entfernen
298         public function removeDraught () {
299                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Tiefgang entfernt.<br />\n",
300                         $this->__toString()
301                 ));
302                 unset($this->draught);
303         }
304
305         // Getter-Methode fuer Element aus resizeFactor
306         public function getResizeFactorElement ($el) {
307                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] getResizeFactorElement erreicht. (element=%s)<br />\n",
308                         $this->__toString(),
309                         $el
310                 ));
311                 if (isset($this->resizeFactorArray[$el])) {
312                         // Element gefunden
313                         return $this->resizeFactorArray[$el];
314                 } else {
315                         // Element nicht gefunden!
316                         return 0;
317                 }
318         }
319
320         // Setter-Methode fuer Element in resizeFactor
321         public function setResizeFactorElement ($el, $value) {
322                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Umberechnungsfaktor <strong>%s</strong>=<strong>%s</strong> gesetzt.<br />\n",
323                         $this->__toString(),
324                         $el,
325                         $value
326                 ));
327                 $this->resizeFactorArray[$el] = (float) $value;
328         }
329
330         // Kontrolliert, ob die Abmasse Schiffsteil->Schiff stimmen
331         public function isShipPartSizeValid () {
332                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isShipPartSizeValid erreicht.<br />\n",
333                         $this->__toString()
334                 ));
335                 return (
336                         (
337                                 ( // Already defined ship messurings
338                                            ($this->currPart->getWidth()  < $this->currShip->getWidth())
339                                         && ($this->currPart->getHeight() < $this->currShip->getDraught())
340                                         && ($this->currPart->getLength() < $this->currShip->getLength())
341                                 ) || ( // Ship messurings shall be calculated
342                                            ($this->currShip->getWidth()  == 0)
343                                         && ($this->currShip->getHeight() == 0)
344                                         && ($this->currShip->getLength() == 0)
345                                 )
346                         // The inserted part must be messured!
347                         ) && ($this->currPart->getWidth()  > 0)
348                           && ($this->currPart->getHeight() > 0)
349                           && ($this->currPart->getLength() > 0)
350                 );
351         }
352
353         // Kontrolliert, ob die Abmasse Maschinenraum->Schiff stimmen
354         public function isNewSizeValid () {
355                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isNewSizeValid erreicht.<br />\n",
356                         $this->__toString()
357                 ));
358                 return (
359                         ( // Already defined ship messurings
360                                    ($this->newWidth  < $this->currShip->getWidth())
361                                 && ($this->newHeight < $this->currShip->getDraught())
362                                 && ($this->newLength < $this->currShip->getLength())
363                         ) || ( // Ship messurings shall be calculated
364                                    ($this->currShip->getWidth()  == 0)
365                                 && ($this->currShip->getHeight() == 0)
366                                 && ($this->currShip->getLength() == 0)
367                         )
368                 );
369         }
370
371         // Masse extrahieren
372         public function extractDimensions ($dim) {
373                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] extractDimensions erreicht f&uuml;r <strong>%s</strong>.<br />\n",
374                         $this->__toString(),
375                         $this->getPartDescr()
376                 ));
377
378                 // Abmasse setzen
379                 if ((isset($dim)) && (is_array($dim)) && (count($dim) == 3)) {
380                         // Abmasse aus Array holen
381                         $this->setWidth($dim[0]);
382                         $this->setHeight($dim[1]);
383                         $this->setLength($dim[2]);
384                 } else {
385                         // Nicht gefundene Abmasse!
386                         throw new DimNotFoundInArrayException($this, self::EXCEPTION_DIMENSION_ARRAY_INVALID);
387                 }
388         }
389 }
390
391 // [EOF]
392 ?>