3 * The general simulator class
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class BaseSimulator extends BaseFrameworkSystem {
26 private $partInstance = null;
28 // Abmasse (Breite/Hoehe/Laenge)
33 // Aktuelles Schiff und Schiffsteil
34 private $currShip = null;
35 private $currPart = null;
37 // Faktoren zur Erweiterung der Masse. Beispielsweise soll der Maschinenraum groesser wie der Motor sein
38 private $resizeFactorArray = array(
45 private function __construct ($class) {
46 // Call highest constructor
47 parent::constructor($class);
49 if ((defined('DEBUG_CORE')) && (defined('DEBUG_CONSTRUCT'))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruktor erreicht.<br />\n",
53 // Set part description and class name
54 $this->setPartDescr("Simulator-Basis-Einheit");
56 // Clean up a little, dies sollte ganz zum Schluss erfolgen!
57 $this->removeResizeFactorArray();
58 $this->removeCurrPart();
59 $this->removeCurrShip();
63 public function constructor ($class) {
64 // Call real constructor
65 $this->__construct($class);
68 // Magic __isset method
69 private function __isset ($var) {
70 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Checking <strong>%s</strong> in class.<br />\n",
71 $this->__toString(), $var
73 return isset($this->$var);
76 // Magic __unset method
77 private function __unset($var) {
78 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Removing <strong>%s</strong> from class.<br />\n",
79 $this->__toString(), $var
84 // Setter-Methode fuer Laenge
85 public final function setLength ($length) {
86 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Länge gesetzt.<br />\n",
90 $this->length = (float) $length;
93 // Setter-Methode fuer Breite
94 public final function setWidth ($width) {
95 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Breite gesetzt.<br />\n",
99 $this->width = (float) $width;
102 // Setter-Methode fuer Hoehe
103 public final function setHeight ($height) {
104 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Höhe gesetzt.<br />\n",
108 $this->height = (float) $height;
111 // Getter-Methode fuer Laenge
112 public final function getLength () {
113 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Länge angefordert.<br />\n",
116 return $this->length;
119 // Getter-Methode fuer Breite
120 public final function getWidth () {
121 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Länge angefordert.<br />\n",
127 // Getter-Methode fuer Hoehe
128 public final function getHeight () {
129 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Höhe angefordert.<br />\n",
132 return $this->height;
135 // Setter-Methode fuer Teil-Instanz
136 public final function setPartInstance (ConstructableShipPart $partInstance) {
137 $this->partInstance = $partInstance;
140 // Getter-Methode fuer Teil-Instanz
141 public final function getPartInstance () {
142 if (!isset($this->partInstance)) {
145 return $this->partInstance;
148 // Remover-Methode fuer die Teil-Instanz
149 public function removePartInstance () {
150 if ($this->getPartInstance() !== null) {
152 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance ist nicht null! Instanz-Attribut wird nicht entfernt.<br />\n",
156 // Leere Instanz kann entfernt werden
157 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance wurde entfernt.<br />\n",
160 unset($this->partInstance);
164 // Prueft ob all Umberechnungsfaktoren gesetzt sind
165 private function isResizeFactorValid () {
166 return (($this->getResizeFactorElement('width') > 1)
167 || ($this->getResizeFactorElement('height') > 1)
168 || ($this->getResizeFactorElement('length') > 1)
172 // Baut einen Motor in das Schiff ein
173 public function addShipPartToShip (ConstructableShip $shipInstance, ConstructableShipPart $partInstance) {
174 // Schiff/-steil merken
175 $this->currShip = $shipInstance;
176 $this->currPart = $partInstance;
178 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",
180 $this->currPart->getPartDescr(),
181 $this->currShip->getShipName()
184 // Passt ueberhaupt das Schiffsteil in's Schiff?
185 if ($this->isShipPartSizeValid()) {
186 // Berechnungen fuer umliegendes Objekt anpassen
187 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",
189 $this->currPart->getPartDescr(),
190 $this->currPart->__toString(),
191 $this->currShip->getShipName()
194 // Muessen die Masse angepasst werden?
195 if ($this->isResizeFactorValid()) {
196 // Neue Angaben berechnen (wir lassen etwas Lust fuer Kabelbaeume, Roehren, Maschinisten, etc.)
197 $this->newWidth = (float) $this->currPart->getWidth() * $this->resizeFactorArray['width'];
198 $this->newHeight = (float) $this->currPart->getHeight() * $this->resizeFactorArray['height'];
199 $this->newLength = (float) $this->currPart->getLength() * $this->resizeFactorArray['length'];
201 // Passt dies nun immer noch?
202 if ($this->isNewSizeValid()) {
203 // Das passt auch, dann Werte setzen und Motor-Instanz merken
204 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> passt in das Schiff <strong>%s</strong> hinein.<br />\n",
206 $this->getPartDescr(),
207 $this->currShip->getShipName()
209 $this->setWidth($this->newWidth);
210 $this->setHeight($this->newHeight);
211 $this->setLength($this->newLength);
213 // Einige Dinge entfernen...
214 $this->removeAllNewAttr();
216 // Passt nicht! Also wieder Exception werfen...
217 throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> vom Typ <strong>%s</strong> ist zu gross für das Schiff!",
218 $this->currPart->__toString(),
219 $this->currPart->getPartDescr(),
220 $this->currPart->__toString()
223 } elseif ($this->currPart != null) {
224 // Aktuelle Masse setzen
225 $this->setWidth($this->currPart->getWidth());
226 $this->setHeight($this->currPart->getHeight());
227 $this->setLength($this->currPart->getLength());
230 // Existiert ein Schiffsteil?
231 if (!is_null($this->currPart)) {
232 // Debug-Meldung ausgeben
233 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Schiffsteil <strong>%s</strong> gefunden.<br />\n",
234 $this->currPart->realClass,
235 $this->currPart->getPartDescr()
238 // Schiffsteil-Instanz setzen
239 $this->setPartInstance($this->currPart);
241 // Instanzen entfernen
242 $this->currPart->removeCurrShip();
243 $this->currPart->removeCurrPart();
244 $this->currPart->removePartInstance();
245 $this->currPart->removeResizeFactorArray();
249 throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <u>%s</u> vom Typ <u>%s</u> passt nicht in das Schiff!",
250 $this->currPart->realClass,
251 $this->currPart->getPartDescr(),
252 $this->currPart->__toString()
256 // Nochmals Clean up a little
257 $this->removeResizeFactorArray();
258 $this->removeCurrShip();
259 $this->removeCurrPart();
262 // Array fuer Umrechnungstabelle entfernen
263 public function removeResizeFactorArray () {
264 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeResizeFactor erreicht.<br />\n",
267 unset($this->resizeFactorArray);
270 // Alle newXXX-Attribute entfernen
271 public function removeAllNewAttr () {
272 unset($this->newWidth);
273 unset($this->newHeight);
274 unset($this->newLength);
277 // Aktuelle Schiff-Instanz entfernen
278 public function removeCurrShip () {
279 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrShip erreicht.<br />\n",
282 unset($this->currShip);
285 // Aktuelle Schiff-Instanz entfernen
286 public function removeCurrPart () {
287 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrPart erreicht.<br />\n",
290 unset($this->currPart);
294 public function removeWidth () {
295 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Breite entfernt.<br />\n",
302 public function removeHeight () {
303 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Höhe entfernt.<br />\n",
306 unset($this->height);
310 public function removeLength () {
311 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Länge entfernt.<br />\n",
314 unset($this->length);
317 // Tiefgang entfernen
318 public function removeDraught () {
319 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Tiefgang entfernt.<br />\n",
322 unset($this->draught);
325 // Getter-Methode fuer Element aus resizeFactor
326 public final function getResizeFactorElement ($el) {
327 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] getResizeFactorElement erreicht. (element=%s)<br />\n",
331 if (isset($this->resizeFactorArray[$el])) {
333 return $this->resizeFactorArray[$el];
335 // Element nicht gefunden!
340 // Setter-Methode fuer Element in resizeFactor
341 public final function setResizeFactorElement ($el, $value) {
342 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Umberechnungsfaktor <strong>%s</strong>=<strong>%s</strong> gesetzt.<br />\n",
347 $this->resizeFactorArray[$el] = (float) $value;
350 // Kontrolliert, ob die Abmasse Schiffsteil->Schiff stimmen
351 public function isShipPartSizeValid () {
352 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isShipPartSizeValid erreicht.<br />\n",
357 ( // Already defined ship messurings
358 ($this->currPart->getWidth() < $this->currShip->getWidth())
359 && ($this->currPart->getHeight() < $this->currShip->getDraught())
360 && ($this->currPart->getLength() < $this->currShip->getLength())
361 ) || ( // Ship messurings shall be calculated
362 ($this->currShip->getWidth() == 0)
363 && ($this->currShip->getHeight() == 0)
364 && ($this->currShip->getLength() == 0)
366 // The inserted part must be messured!
367 ) && ($this->currPart->getWidth() > 0)
368 && ($this->currPart->getHeight() > 0)
369 && ($this->currPart->getLength() > 0)
373 // Kontrolliert, ob die Abmasse Maschinenraum->Schiff stimmen
374 public function isNewSizeValid () {
375 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isNewSizeValid erreicht.<br />\n",
379 ( // Already defined ship messurings
380 ($this->newWidth < $this->currShip->getWidth())
381 && ($this->newHeight < $this->currShip->getDraught())
382 && ($this->newLength < $this->currShip->getLength())
383 ) || ( // Ship messurings shall be calculated
384 ($this->currShip->getWidth() == 0)
385 && ($this->currShip->getHeight() == 0)
386 && ($this->currShip->getLength() == 0)
392 public function extractDimensions ($dim) {
393 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] extractDimensions erreicht für <strong>%s</strong>.<br />\n",
395 $this->getPartDescr()
399 if ((isset($dim)) && (is_array($dim)) && (count($dim) == 3)) {
400 // Abmasse aus Array holen
401 $this->setWidth($dim[0]);
402 $this->setHeight($dim[1]);
403 $this->setLength($dim[2]);
405 // Nicht gefundene Abmasse!
406 throw new DimNotFoundInArrayException($this, self::EXCEPTION_DIMENSION_ARRAY_INVALID);