Completed
Push — master ( 6c7852...c45dbb )
by De Cramer
14s
created

ScriptVariableUpdateFactory::onEverySecond()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
cc 1
eloc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace eXpansion\Framework\Core\Plugins\Gui;
4
5
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpTimer;
6
use eXpansion\Framework\Core\DataProviders\Listener\ListenerInterfaceExpUserGroup;
7
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
8
use eXpansion\Framework\Core\Model\Gui\Script\Variable;
9
use eXpansion\Framework\Core\Model\Gui\WidgetFactoryContext;
10
use eXpansion\Framework\Core\Model\UserGroups\Group;
11
use FML\Script\Builder;
12
use FML\Script\Script;
13
use FML\Script\ScriptLabel;
14
15
/**
16
 * Class ScriptVariableUpdateFactory
17
 *
18
 * @author    de Cramer Oliver<[email protected]>
19
 * @copyright 2018 eXpansion
20
 * @package eXpansion\Framework\Core\Plugins\Gui
21
 */
22
class ScriptVariableUpdateFactory extends WidgetFactory implements ListenerInterfaceExpTimer, ListenerInterfaceExpUserGroup
23
{
24
    /** @var Variable[] */
25
    protected $variables = [];
26
27
    /** @var Variable */
28
    protected $checkVariable;
29
30
    /** @var float */
31
    protected $maxUpdateFrequency;
32
33
    /** @var Variable */
34
    protected $checkOldVariable;
35
36
    /** @var mixed[][] */
37
    protected $queuedForUpdate = [];
38
39
    /** @var Variable */
40
    protected $checkWindow;
41
42
43
    /**
44
     * ScriptVariableUpdateFactory constructor.
45
     *
46
     * @param                      $name
47
     * @param array                $variables
48
     * @param float                $maxUpdateFrequency
49
     * @param WidgetFactoryContext $context
50
     */
51
    public function __construct(
52
        $name,
53
        array $variables,
54
        float $maxUpdateFrequency = 0.250,
55
        WidgetFactoryContext $context
56
    ) {
57
        parent::__construct($name, 0, 0, 0, 0, $context);
58
        $this->maxUpdateFrequency = $maxUpdateFrequency;
59
60
        foreach ($variables as $variable) {
61
            $this->variables[$variable['name']] = new Variable(
62
                $variable['name'],
63
                $variable['type'],
64
                'This',
65
                $variable['default']
66
            );
67
        }
68
69
        $uniqueId = uniqid('exp_', true);
70
        $this->checkVariable = new Variable('check', 'Text', 'This', "\"$uniqueId\"");
71
        $this->checkOldVariable = new Variable('check_old', 'Text', 'Page', "\"$uniqueId\"");
72
        $this->checkWindow = new Variable('check_window', 'Text', 'This', Builder::escapeText(md5(get_called_class())));
73
    }
74
75
    /**
76
     * Update script value.
77
     *
78
     * @param Group  $group
79
     * @param string $variableCode
80
     * @param string $newValue
81
     */
82
    public function updateValue($group, $variableCode, $newValue)
83
    {
84
        $variable = clone $this->getVariable($variableCode);
85
        $variable->setValue($newValue);
86
87
        if (!isset($this->queuedForUpdate[$group->getName()])) {
88
            $this->queuedForUpdate[$group->getName()]['time'] = microtime(true);
89
        }
90
91
        $checkVariable = clone $this->checkVariable;
92
        $uniqueId = uniqid('exp_', true);
93
        $checkVariable->setValue("\"$uniqueId\"");
94
95
        $this->checkWindow->setValue(Builder::escapeText(get_called_class()));
96
        $this->queuedForUpdate[$group->getName()]['group'] = $group;
97
        $this->queuedForUpdate[$group->getName()]['variables'][$variableCode] = $variable;
98
        $this->queuedForUpdate[$group->getName()]['check'] = $checkVariable;
99
    }
100
101
    /**
102
     * Get a variable.
103
     *
104
     * @param $variable
105
     *
106
     * @return Variable
107
     */
108
    public function getVariable($variable)
109
    {
110
        return $this->variables[$variable];
111
    }
112
113
    /**
114
     * Get variable to use to check if data needs to be updated.
115
     *
116
     * @return Variable
117
     */
118
    public function getCheckVariable()
119
    {
120
        return $this->checkVariable;
121
    }
122
123
    /**
124
     * Get script to execute when there is a change.
125
     *
126
     * @param string $toExecute Script to execute.
127
     *
128
     * @return string
129
     */
130
    public function getScriptOnChange($toExecute)
131
    {
132
        return <<<EOL
133
            if ( {$this->checkVariable->getVariableName()} != {$this->checkOldVariable->getVariableName()}) {
134
                  {$this->checkOldVariable->getVariableName()} = {$this->checkVariable->getVariableName()};
135
                  if ( check_original == {$this->checkWindow->getVariableName()} ) {        
136
                        $toExecute
137
                  }
138
            }
139
EOL;
140
    }
141
142
    /**
143
     * Get initialization script.
144
     *
145
     * @param bool $defaultValues
146
     * @return string
147
     */
148
    public function getScriptInitialization($defaultValues = false)
149
    {
150
        $scriptContent = '';
151
        foreach ($this->variables as $variable) {
152
            $scriptContent .= $variable->getScriptDeclaration()."\n";
153
            if ($defaultValues) {
154
                $scriptContent .= $variable->getScriptValueSet()."\n";
155
            }
156
        }
157
158
        $scriptContent .= $this->checkVariable->getScriptDeclaration()."\n";
159
        $scriptContent .= $this->checkOldVariable->getScriptDeclaration()."\n";
160
        $scriptContent .= $this->checkWindow->getScriptDeclaration()."\n";
161
        $scriptContent .= "declare check_original = ".$this->checkWindow->getInitialValue().";\n";
162
163
        if ($defaultValues) {
164
            $scriptContent .= $this->checkVariable->getScriptValueSet()."\n";
165
            $scriptContent .= $this->checkOldVariable->getScriptValueSet()."\n";
166
            $scriptContent .= $this->checkWindow->getScriptValueSet()."\n";
167
        }
168
169
        return $scriptContent;
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175
    protected function updateContent(ManialinkInterface $manialink)
176
    {
177
        // Empty existing script.
178
        parent::updateContent($manialink);
179
        $manialink->getFmlManialink()->removeAllChildren();
180
181
        // sets timeout for displaying the manialink page
182
        $manialink->setTimeout(2000);
183
184
        // create hash.
185
        $this->checkWindow->setValue(Builder::escapeText(md5(get_called_class())));
186
        // Get script with new values.
187
        $scriptContent = $this->getScriptInitialization(true);
188
189
        // Update FML Manialink
190
        $script = new Script();
191
        $script->addCustomScriptLabel(ScriptLabel::OnInit, $scriptContent);
192
        $manialink->getFmlManialink()->setScript($script);
193
194
        $this->queuedForUpdate = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array<integer,array<integer,*>> of property $queuedForUpdate.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
195
    }
196
197
    /**
198
     * @inheritdoc
199
     */
200
    public function onPreLoop()
201
    {
202
        if (!empty($this->queuedForUpdate)) {
203
            foreach ($this->queuedForUpdate as $groupName => $updateData) {
204
                if (microtime(true) - $updateData['time'] >= $this->maxUpdateFrequency) {
205
                    // Save original data.
206
                    $variables = $this->variables;
207
                    $checkVariable = $this->checkVariable;
208
                    $checkWindow = $this->checkWindow;
209
210
                    // Update variables temporarily with player data.
211
                    $this->variables = [];
212
                    foreach ($updateData['variables'] as $variableCode => $variable) {
213
                        $this->variables[$variableCode] = $variable;
214
                    }
215
                    $this->checkVariable = $updateData['check'];
216
217
                    $this->create($updateData['group']);
218
219
                    // Put back original data.
220
                    $this->variables = $variables;
221
                    $this->checkVariable = $checkVariable;
222
                    $this->checkWindow = $checkWindow;
223
224
                    unset($this->queuedForUpdate[$groupName]);
225
                }
226
            }
227
        }
228
    }
229
230
    /**
231
     * @inheritdoc
232
     */
233
    public function onPostLoop()
234
    {
235
        // Nothing
236
    }
237
238
    /**
239
     * @inheritdoc
240
     */
241
    public function onEverySecond()
242
    {
243
244
    }
245
246
    /**
247
     * @inheritdoc
248
     */
249
    public function onExpansionGroupAddUser(Group $group, $loginAdded)
250
    {
251
        // This will be handled by the gui handler.
252
    }
253
254
    /**
255
     * @inheritdoc
256
     */
257
    public function onExpansionGroupRemoveUser(Group $group, $loginRemoved)
258
    {
259
        // This will be handled by the gui handler.
260
    }
261
262
    /**
263
     * @inheritdoc
264
     */
265
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
266
    {
267
        if (isset($this->queuedForUpdate[$group->getName()])) {
268
            unset($this->queuedForUpdate[$group->getName()]);
269
        }
270
    }
271
}
272