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 protected function __construct ($class) {
46 // Call highest constructor
47 parent::__construct($class);
49 // Set part description and class name
50 $this->setObjectDescription("Simulator-Basis-Einheit");
52 // Clean up a little, dies sollte ganz zum Schluss erfolgen!
53 $this->removeResizeFactorArray();
54 $this->removeCurrPart();
55 $this->removeCurrShip();
58 // Setter-Methode fuer Laenge
59 public final function setLength ($length) {
60 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Länge gesetzt.<br />\n",
64 $this->length = (float) $length;
67 // Setter-Methode fuer Breite
68 public final function setWidth ($width) {
69 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Breite gesetzt.<br />\n",
73 $this->width = (float) $width;
76 // Setter-Methode fuer Hoehe
77 public final function setHeight ($height) {
78 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Höhe gesetzt.<br />\n",
82 $this->height = (float) $height;
85 // Getter-Methode fuer Laenge
86 public final function getLength () {
87 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Länge angefordert.<br />\n",
93 // Getter-Methode fuer Breite
94 public final function getWidth () {
95 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Länge angefordert.<br />\n",
101 // Getter-Methode fuer Hoehe
102 public final function getHeight () {
103 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Höhe angefordert.<br />\n",
106 return $this->height;
109 // Setter-Methode fuer Teil-Instanz
110 public final function setPartInstance (ConstructableShipPart $partInstance) {
111 $this->partInstance = $partInstance;
114 // Getter-Methode fuer Teil-Instanz
115 public final function getPartInstance () {
116 if (!isset($this->partInstance)) {
119 return $this->partInstance;
122 // Remover-Methode fuer die Teil-Instanz
123 public final function removePartInstance () {
124 if ($this->getPartInstance() !== null) {
126 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance ist nicht null! Instanz-Attribut wird nicht entfernt.<br />\n",
130 // Leere Instanz kann entfernt werden
131 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance wurde entfernt.<br />\n",
134 unset($this->partInstance);
138 // Prueft ob all Umberechnungsfaktoren gesetzt sind
139 private function isResizeFactorValid () {
140 return (($this->getResizeFactorElement('width') > 1)
141 || ($this->getResizeFactorElement('height') > 1)
142 || ($this->getResizeFactorElement('length') > 1)
146 // Baut einen Motor in das Schiff ein
147 public function addShipPartToShip (ConstructableShip $shipInstance, ConstructableShipPart $partInstance) {
148 // Schiff/-steil merken
149 $this->currShip = $shipInstance;
150 $this->currPart = $partInstance;
152 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",
154 $this->getCurrPart()->getObjectDescription(),
155 $this->currShip->getShipName()
158 // Passt ueberhaupt das Schiffsteil in's Schiff?
159 if ($this->isShipPartSizeValid()) {
160 // Berechnungen fuer umliegendes Objekt anpassen
161 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",
163 $this->getCurrPart()->getObjectDescription(),
164 $this->getCurrPart()->__toString(),
165 $this->currShip->getShipName()
168 // Muessen die Masse angepasst werden?
169 if ($this->isResizeFactorValid()) {
170 // Neue Angaben berechnen (wir lassen etwas Lust fuer Kabelbaeume, Roehren, Maschinisten, etc.)
171 $this->newWidth = (float) $this->getCurrPart()->getWidth() * $this->resizeFactorArray['width'];
172 $this->newHeight = (float) $this->getCurrPart()->getHeight() * $this->resizeFactorArray['height'];
173 $this->newLength = (float) $this->getCurrPart()->getLength() * $this->resizeFactorArray['length'];
175 // Passt dies nun immer noch?
176 if ($this->isNewSizeValid()) {
177 // Das passt auch, dann Werte setzen und Motor-Instanz merken
178 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> passt in das Schiff <strong>%s</strong> hinein.<br />\n",
180 $this->getObjectDescription(),
181 $this->currShip->getShipName()
183 $this->setWidth($this->newWidth);
184 $this->setHeight($this->newHeight);
185 $this->setLength($this->newLength);
187 // Einige Dinge entfernen...
188 $this->removeAllNewAttr();
190 // Passt nicht! Also wieder Exception werfen...
191 throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> vom Typ <strong>%s</strong> ist zu gross für das Schiff!",
192 $this->getCurrPart()->__toString(),
193 $this->getCurrPart()->getObjectDescription(),
194 $this->getCurrPart()->__toString()
197 } elseif ($this->currPart != null) {
198 // Aktuelle Masse setzen
199 $this->setWidth($this->getCurrPart()->getWidth());
200 $this->setHeight($this->getCurrPart()->getHeight());
201 $this->setLength($this->getCurrPart()->getLength());
204 // Existiert ein Schiffsteil?
205 if (!is_null($this->currPart)) {
206 // Debug-Meldung ausgeben
207 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Schiffsteil <strong>%s</strong> gefunden.<br />\n",
208 $this->getCurrPart()->realClass,
209 $this->getCurrPart()->getObjectDescription()
212 // Schiffsteil-Instanz setzen
213 $this->setPartInstance($this->currPart);
215 // Instanzen entfernen
216 $this->getCurrPart()->removeCurrShip();
217 $this->getCurrPart()->removeCurrPart();
218 $this->getCurrPart()->removePartInstance();
219 $this->getCurrPart()->removeResizeFactorArray();
223 throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <u>%s</u> vom Typ <u>%s</u> passt nicht in das Schiff!",
224 $this->getCurrPart()->realClass,
225 $this->getCurrPart()->getObjectDescription(),
226 $this->getCurrPart()->__toString()
230 // Nochmals Clean up a little
231 $this->removeResizeFactorArray();
232 $this->removeCurrShip();
233 $this->removeCurrPart();
236 // Array fuer Umrechnungstabelle entfernen
237 public final function removeResizeFactorArray () {
238 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeResizeFactor erreicht.<br />\n",
241 unset($this->resizeFactorArray);
245 * Remove all new*** attributes
249 public final function removeAllNewAttr () {
250 unset($this->newWidth);
251 unset($this->newHeight);
252 unset($this->newLength);
256 * Remove current ship instance
260 public final function removeCurrShip () {
261 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrShip erreicht.<br />\n",
264 unset($this->currShip);
267 // Aktuelle Schiffsteil-Instanz entfernen
268 public final function removeCurrPart () {
269 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrPart erreicht.<br />\n",
272 unset($this->currPart);
276 public final function removeWidth () {
277 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Breite entfernt.<br />\n",
284 public final function removeHeight () {
285 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Höhe entfernt.<br />\n",
288 unset($this->height);
292 public final function removeLength () {
293 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Länge entfernt.<br />\n",
296 unset($this->length);
299 // Tiefgang entfernen
300 public final function removeDraught () {
301 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Tiefgang entfernt.<br />\n",
304 unset($this->draught);
307 // Getter-Methode fuer Element aus resizeFactor
308 public final function getResizeFactorElement ($el) {
309 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] getResizeFactorElement erreicht. (element=%s)<br />\n",
313 if (isset($this->resizeFactorArray[$el])) {
315 return $this->resizeFactorArray[$el];
317 // Element nicht gefunden!
322 // Setter-Methode fuer Element in resizeFactor
323 public final function setResizeFactorElement ($el, $value) {
324 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Umberechnungsfaktor <strong>%s</strong>=<strong>%s</strong> gesetzt.<br />\n",
329 $this->resizeFactorArray[$el] = (float) $value;
332 // Kontrolliert, ob die Abmasse Schiffsteil->Schiff stimmen
333 public function isShipPartSizeValid () {
334 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isShipPartSizeValid erreicht.<br />\n",
339 ( // Already defined ship messurings
340 ($this->getCurrPart()->getWidth() < $this->currShip->getWidth())
341 && ($this->getCurrPart()->getHeight() < $this->currShip->getDraught())
342 && ($this->getCurrPart()->getLength() < $this->currShip->getLength())
343 ) || ( // Ship messurings shall be calculated
344 ($this->currShip->getWidth() == 0)
345 && ($this->currShip->getHeight() == 0)
346 && ($this->currShip->getLength() == 0)
348 // The inserted part must be messured!
349 ) && ($this->getCurrPart()->getWidth() > 0)
350 && ($this->getCurrPart()->getHeight() > 0)
351 && ($this->getCurrPart()->getLength() > 0)
355 // Kontrolliert, ob die Abmasse Maschinenraum->Schiff stimmen
356 public function isNewSizeValid () {
357 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isNewSizeValid erreicht.<br />\n",
361 ( // Already defined ship messurings
362 ($this->newWidth < $this->currShip->getWidth())
363 && ($this->newHeight < $this->currShip->getDraught())
364 && ($this->newLength < $this->currShip->getLength())
365 ) || ( // Ship messurings shall be calculated
366 ($this->currShip->getWidth() == 0)
367 && ($this->currShip->getHeight() == 0)
368 && ($this->currShip->getLength() == 0)
374 public function extractDimensions ($dim) {
375 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] extractDimensions erreicht für <strong>%s</strong>.<br />\n",
377 $this->getObjectDescription()
381 if ((isset($dim)) && (is_array($dim)) && (count($dim) == 3)) {
382 // Abmasse aus Array holen
383 $this->setWidth($dim[0]);
384 $this->setHeight($dim[1]);
385 $this->setLength($dim[2]);
387 // Nicht gefundene Abmasse!
388 throw new DimNotFoundInArrayException($this, self::EXCEPTION_DIMENSION_ARRAY_INVALID);
393 * Getter for current part instance
395 * @return $currPart Instance of the current ship part object
397 public final function getCurrPart () {
398 return $this->currPart;