Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
9 / 9 |
CRAP | |
100.00% |
46 / 46 |
StateMachineProcessor | |
100.00% |
1 / 1 |
|
100.00% |
9 / 9 |
22 | |
100.00% |
46 / 46 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
setPrefix | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
processGraph | |
100.00% |
1 / 1 |
3 | |
100.00% |
4 / 4 |
|||
processNodeAttrs | |
100.00% |
1 / 1 |
5 | |
100.00% |
15 / 15 |
|||
processEdgeAttrs | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
runGraphProcessor | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
runNodeProcessor | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
runEdgeProcessor | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
getExtraSvgElements | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
<?php declare(strict_types = 1); | |
/* | |
* Copyright (c) 2019, Josef Kufner <josef@kufner.cz> | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
*/ | |
namespace Smalldb\StateMachine\Definition\Renderer; | |
use Smalldb\StateMachine\Definition\ExtensibleDefinition; | |
use Smalldb\StateMachine\Definition\StateMachineGraph\StateMachineEdge; | |
use Smalldb\StateMachine\Definition\StateMachineGraph\StateMachineGraph; | |
use Smalldb\StateMachine\Definition\StateMachineGraph\StateMachineNode; | |
use Smalldb\Graph\Edge; | |
use Smalldb\Graph\Grafovatko\ProcessorInterface; | |
use Smalldb\Graph\Graph; | |
use Smalldb\Graph\NestedGraph; | |
use Smalldb\Graph\Node; | |
class StateMachineProcessor implements ProcessorInterface | |
{ | |
private string $prefix; | |
private bool $horizontalLayout; | |
public function __construct(bool $horizontalLayout = false) | |
{ | |
$this->horizontalLayout = $horizontalLayout; | |
} | |
public function setPrefix(string $prefix): void | |
{ | |
$this->prefix = $prefix; | |
} | |
/** | |
* Returns modified $exportedGraph which become the graph's attributes. | |
* | |
* @param NestedGraph $graph | |
* @param array $exportedGraph | |
* @return array | |
*/ | |
public function processGraph(NestedGraph $graph, array $exportedGraph): array | |
{ | |
if ($graph instanceof StateMachineGraph) { | |
$exportedGraph['layoutOptions']['rankdir'] = $this->horizontalLayout ? 'LR' : 'TB'; | |
$this->runGraphProcessor($graph->getStateMachine(), $graph, $exportedGraph); | |
} | |
return $exportedGraph; | |
} | |
/** | |
* Returns modified $exportedNode which become the node's attributes. | |
*/ | |
public function processNodeAttrs(Node $node, array $exportedNode): array | |
{ | |
if ($node instanceof StateMachineNode) { | |
$state = $node->getState(); | |
$stateName = $state->getName(); | |
$exportedNode['label'] = $stateName; | |
$exportedNode['fill'] = "#eee"; | |
if ($stateName === '') { | |
if ($node->isSourceNode()) { | |
$exportedNode['shape'] = 'uml.initial_state'; | |
} else if (empty($node->getConnectedEdges())) { | |
$exportedNode['shape'] = 'none'; | |
} else { | |
$exportedNode['shape'] = 'uml.final_state'; | |
} | |
} else { | |
$exportedNode['shape'] = 'uml.state'; | |
} | |
$this->runNodeProcessor($node->getStateMachine(), $node, $exportedNode); | |
$this->runNodeProcessor($state, $node, $exportedNode); | |
// TODO: Highlight unreachable and undefined states | |
} | |
return $exportedNode; | |
} | |
/** | |
* Returns modified $exportedEdge which become the edge's attributes. | |
*/ | |
public function processEdgeAttrs(Edge $edge, array $exportedEdge): array | |
{ | |
if ($edge instanceof StateMachineEdge) { | |
$transition = $edge->getTransition(); | |
$exportedEdge['label'] = $transition->getName(); | |
$exportedEdge['color'] = "#000"; | |
$this->runEdgeProcessor($transition, $edge, $exportedEdge); | |
$this->runEdgeProcessor($edge->getStateMachine(), $edge, $exportedEdge); | |
} | |
return $exportedEdge; | |
} | |
private function runGraphProcessor(ExtensibleDefinition $definition, StateMachineGraph $graph, array &$exportedGraph) | |
{ | |
foreach ($definition->getExtensionClassNames() as $extName) { | |
$ext = $definition->getExtension($extName); | |
if ($ext instanceof StateMachineGraphProcessor) { | |
$ext->processGraphAttrs($graph, $exportedGraph); | |
} | |
} | |
} | |
private function runNodeProcessor(ExtensibleDefinition $definition, StateMachineNode $node, array &$exportedNode) | |
{ | |
foreach ($definition->getExtensionClassNames() as $extName) { | |
$ext = $definition->getExtension($extName); | |
if ($ext instanceof StateMachineNodeProcessor) { | |
$ext->processNodeAttrs($node, $exportedNode); | |
} | |
} | |
} | |
private function runEdgeProcessor(ExtensibleDefinition $definition, StateMachineEdge $edge, array &$exportedEdge) | |
{ | |
foreach ($definition->getExtensionClassNames() as $extName) { | |
$ext = $definition->getExtension($extName); | |
if ($ext instanceof StateMachineEdgeProcessor) { | |
$ext->processEdgeAttrs($edge, $exportedEdge); | |
} | |
} | |
} | |
/** | |
* Returns Htag-style array of additional SVG elements which will be appended to the rendered SVG image. | |
*/ | |
public function getExtraSvgElements(Graph $graph): array | |
{ | |
return []; | |
} | |
} |