début réorganisation log

This commit is contained in:
Jephté Clain 2025-10-15 12:13:49 +04:00
parent 51215b42eb
commit 55728059cf
10 changed files with 326 additions and 224 deletions

View File

@ -17,6 +17,21 @@
</DockerContainerSettings>
</value>
</entry>
<entry key="385aa179-8c50-45e2-9ad7-4d9bfba298a3">
<value>
<DockerContainerSettings>
<option name="version" value="1" />
<option name="volumeBindings">
<list>
<DockerVolumeBindingImpl>
<option name="containerPath" value="/opt/project" />
<option name="hostPath" value="$PROJECT_DIR$" />
</DockerVolumeBindingImpl>
</list>
</option>
</DockerContainerSettings>
</value>
</entry>
<entry key="38915385-b3ff-4f4b-8a9a-d5f3ecae559e">
<value>
<DockerContainerSettings>

4
.idea/php.xml generated
View File

@ -2,7 +2,7 @@
<project version="4">
<component name="MessDetector">
<phpmd_settings>
<phpmd_by_interpreter asDefaultInterpreter="true" interpreter_id="846389f7-9fb5-4173-a868-1dc6b8fbb3fa" timeout="30000" />
<phpmd_by_interpreter asDefaultInterpreter="true" interpreter_id="38915385-b3ff-4f4b-8a9a-d5f3ecae559e" timeout="30000" />
</phpmd_settings>
</component>
<component name="MessDetectorOptionsConfiguration">
@ -17,7 +17,7 @@
</component>
<component name="PhpCodeSniffer">
<phpcs_settings>
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="846389f7-9fb5-4173-a868-1dc6b8fbb3fa" timeout="30000" />
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="38915385-b3ff-4f4b-8a9a-d5f3ecae559e" timeout="30000" />
</phpcs_settings>
</component>
<component name="PhpIncludePathManager">

View File

@ -11,9 +11,14 @@ trait _TMessenger {
static function set_messenger(IMessenger $msg, bool $replace=false): IMessenger {
if (self::$msg instanceof NullMessenger) self::$msg = null;
if ($replace || self::$msg === null) return self::$msg = $msg;
elseif (self::$msg instanceof ProxyMessenger) self::$msg->addMessenger($msg);
else self::$msg = new ProxyMessenger(self::$msg);
if ($replace || self::$msg === null) {
return self::$msg = $msg;
} elseif (self::$msg instanceof ProxyMessenger) {
self::$msg->addMessenger($msg);
} else {
self::$msg = new ProxyMessenger(self::$msg);
self::$msg->addMessenger($msg);
}
return $msg;
}

View File

@ -49,8 +49,12 @@ abstract class AbstractMessenger implements _IMessenger {
protected int $lastTitleId = 1;
protected abstract function title__getId(): ?int;
protected int $lastActionId = 1;
protected abstract function action__getId(): ?int;
protected function getLinePrefix(): ?string {
$linePrefix = null;
if ($this->addDate) {
@ -59,9 +63,9 @@ abstract class AbstractMessenger implements _IMessenger {
}
if ($this->showIds) {
if ($this->id !== null) $linePrefix .= "p=$this->id ";
$titleId = $this->_getTitleId();
$titleId = $this->title__getId();
if ($titleId !== null) $linePrefix .= "t=$titleId ";
$actionId = $this->_getActionId();
$actionId = $this->action__getId();
if ($actionId !== null) $linePrefix .= "a=$actionId ";
}
return $linePrefix;
@ -129,7 +133,7 @@ abstract class AbstractMessenger implements _IMessenger {
}
}
protected abstract function flushActions(bool $endAction=false, ?int $overrideLevel=null): void;
protected abstract function action__flush(bool $endAction=false, ?int $overrideLevel=null): void;
protected function _printAction(
?string $linePrefix, int $level,
@ -269,7 +273,7 @@ abstract class AbstractMessenger implements _IMessenger {
$flushActions = true;
$showContent = $this->checkLevel($level);
if ($content !== null && $showContent) {
$this->flushActions(); $flushActions = false;
$this->action__flush(); $flushActions = false;
$this->_printGeneric($linePrefix, $level, $type, $content, $indentLevel, $out);
}
if ($exceptions !== null) {
@ -279,12 +283,12 @@ abstract class AbstractMessenger implements _IMessenger {
# tout d'abord message
$message = exceptions::get_message($exception);
if ($showContent) {
if ($flushActions) { $this->flushActions(); $flushActions = false; }
if ($flushActions) { $this->action__flush(); $flushActions = false; }
$this->_printGeneric($linePrefix, $level, $type, $message, $indentLevel, $out);
}
# puis summary et traceback
if ($showTraceback) {
if ($flushActions) { $this->flushActions(); $flushActions = false; }
if ($flushActions) { $this->action__flush(); $flushActions = false; }
$summary = exceptions::get_summary($exception, false);
$this->_printGeneric($linePrefix, $level1, $type, $summary, $indentLevel, $out);
$traceback = exceptions::get_traceback($exception);

View File

@ -108,8 +108,19 @@ class ConsoleMessenger extends AbstractMessenger {
/** @var array section qui est en attente d'affichage */
protected ?array $section;
protected function section__end(): void {
while ($this->actions) $this->adone();
while ($this->titles) $this->title__end();
$this->inSection = false;
$this->section = null;
}
function section__afterFunc(): void {
$this->section__end();
}
function section($content, ?callable $func=null, ?int $level=null): void {
$this->_endSection();
$this->section__end();
$this->inSection = true;
if (!$this->checkLevel($level)) return;
$this->section = [
@ -122,7 +133,7 @@ class ConsoleMessenger extends AbstractMessenger {
try {
$func($this);
} finally {
$this->_endSection();
$this->section__afterFunc();
}
}
}
@ -138,13 +149,6 @@ class ConsoleMessenger extends AbstractMessenger {
}
}
function _endSection(): void {
while ($this->actions) $this->adone();
while ($this->titles) $this->_endTitle();
$this->inSection = false;
$this->section = null;
}
protected function getIndentLevel(bool $withActions=true): int {
$indentLevel = count($this->titles) - 1;
if ($indentLevel < 0) $indentLevel = 0;
@ -159,63 +163,26 @@ class ConsoleMessenger extends AbstractMessenger {
protected array $titles;
function _getTitleMark(): int {
return count($this->titles);
function title__getMarks(): array {
return [count($this->titles)];
}
function _getTitleId(): ?int {
protected function title__getId(): ?int {
return end($this->titles)["id"] ?? null;
}
function title($content, ?callable $func=null, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$titleLevel = $this->_getTitleMark();
// faire en deux temps pour linePrefix soit à jour
$this->titles[] = ["id" => $this->lastTitleId++];
A::merge($this->titles[array_key_last($this->titles)], [
"title_level" => $titleLevel,
"max_title_level" => null,
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
"print_content" => true,
"descs" => [],
"print_descs" => false,
]);
if ($func !== null) {
try {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = $titleLevel + 1;
$func($this);
} finally {
$title["max_title_level"] = null;
$this->_endTitle($titleLevel);
protected function title__end(?int $until=null): void {
$title = $this->titles[array_key_last($this->titles)] ?? null;
if ($title !== null) {
$until ??= $title["max_title_level"];
$until ??= $this->title__getMarks()[0] - 1;
while (count($this->titles) > $until) {
array_pop($this->titles);
}
}
}
function desc($content, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$desc = [
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
];
$key = array_key_last($this->titles);
if ($key !== null) {
$title =& $this->titles[$key];
$title["descs"][] = $desc;
$title["print_descs"] = true;
} else {
# pas de titre en cours
$this->_printGeneric(
$desc["line_prefix"], $desc["level"],
"desc", $desc["content"],
0, $this->err);
}
}
protected function flushTitles(): void {
protected function title__flush(): void {
$this->printSection();
$err = $this->err;
$indentLevel = 0;
@ -241,29 +208,86 @@ class ConsoleMessenger extends AbstractMessenger {
}; unset($title);
}
function _endTitle(?int $until=null): void {
$title = $this->titles[array_key_last($this->titles)] ?? null;
if ($title !== null) {
$until ??= $title["max_title_level"];
$until ??= $this->_getTitleMark() - 1;
while (count($this->titles) > $until) {
array_pop($this->titles);
function title__beforeFunc(array $marks): void {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = $marks[0] + 1;
}
function title__afterFunc(array $marks): void {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = null;
$this->title__end($marks[0]);
}
function title($content, ?callable $func=null, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$marks = $this->title__getMarks();
// faire en deux temps pour linePrefix soit à jour
$this->titles[] = ["id" => $this->lastTitleId++];
A::merge($this->titles[array_key_last($this->titles)], [
"title_level" => $marks[0],
"max_title_level" => null,
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
"print_content" => true,
"descs" => [],
"print_descs" => false,
]);
if ($func !== null) {
try {
$this->title__beforeFunc($marks);
$func($this);
} finally {
$this->title__afterFunc($marks);
}
}
}
function desc($content, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$desc = [
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
];
$key = array_key_last($this->titles);
if ($key !== null) {
$title =& $this->titles[$key];
$title["descs"][] = $desc;
$title["print_descs"] = true;
} else {
# pas de titre en cours
$this->_printGeneric(
$desc["line_prefix"], $desc["level"],
"desc", $desc["content"],
0, $this->err);
}
}
protected array $actions;
function _getActionMark(): int {
return count($this->actions);
function action__getMarks(): array {
return [count($this->actions)];
}
function _getActionId(): ?int {
protected function action__getId(): ?int {
return end($this->actions)["id"] ?? null;
}
protected function flushActions(bool $endAction=false, ?int $overrideLevel=null): void {
$this->flushTitles();
protected function action__end(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)] ?? null;
if ($action !== null) {
$until ??= $action["max_action_level"];
$until ??= $this->action__getMarks()[0] - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
}
protected function action__flush(bool $endAction=false, ?int $overrideLevel=null): void {
$this->title__flush();
$err = $this->err;
$indentLevel = $this->getIndentLevel(false);
$lastIndex = array_key_last($this->actions);
@ -311,16 +335,27 @@ class ConsoleMessenger extends AbstractMessenger {
}
$indentLevel++;
}; unset($action);
if ($endAction) $this->_endAction();
if ($endAction) $this->action__end();
}
function action__beforeFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = $marks[0] + 1;
}
function action__afterFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = null;
$this->action__end($marks[0]);
}
function action($content, ?callable $func=null, ?int $level=null): void {
$this->checkLevel($level);
$actionLevel = $this->_getActionMark();
$marks = $this->action__getMarks();
// faire en deux temps pour linePrefix soit à jour
$this->actions[] = ["id" => $this->lastActionId++];
A::merge($this->actions[array_key_last($this->actions)], [
"action_level" => $actionLevel,
"action_level" => $marks[0],
"max_action_level" => null,
"timestamp" => time(),
"line_prefix" => $this->getLinePrefix(),
@ -332,18 +367,16 @@ class ConsoleMessenger extends AbstractMessenger {
]);
if ($func !== null) {
try {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = $actionLevel + 1;
$this->action__beforeFunc($marks);
$result = $func($this);
if ($this->_getActionMark() > $actionLevel) {
if ($this->action__getMarks()[0] > $marks[0]) {
$this->aresult($result);
}
} catch (Exception $e) {
$this->afailure($e);
throw $e;
} finally {
$action["max_action_level"] = null;
$this->_endAction($actionLevel);
$this->action__afterFunc($marks);
}
}
}
@ -359,7 +392,7 @@ class ConsoleMessenger extends AbstractMessenger {
$action =& $this->actions[array_key_last($this->actions)];
$action["result_success"] = true;
$action["result_content"] = $content;
$this->flushActions(true, $overrideLevel);
$this->action__flush(true, $overrideLevel);
}
function afailure($content=null, ?int $overrideLevel=null): void {
@ -367,7 +400,7 @@ class ConsoleMessenger extends AbstractMessenger {
$action =& $this->actions[array_key_last($this->actions)];
$action["result_success"] = false;
$action["result_content"] = $content;
$this->flushActions(true, $overrideLevel);
$this->action__flush(true, $overrideLevel);
}
function adone($content=null, ?int $overrideLevel=null): void {
@ -375,7 +408,7 @@ class ConsoleMessenger extends AbstractMessenger {
$action =& $this->actions[array_key_last($this->actions)];
$action["result_success"] = null;
$action["result_content"] = $content;
$this->flushActions(true, $overrideLevel);
$this->action__flush(true, $overrideLevel);
}
function aresult($result=null, ?int $overrideLevel=null): void {
@ -386,17 +419,6 @@ class ConsoleMessenger extends AbstractMessenger {
else $this->adone($result, $overrideLevel);
}
function _endAction(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)] ?? null;
if ($action !== null) {
$until ??= $action["max_action_level"];
$until ??= $this->_getActionMark() - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
}
function print($content, ?int $level=null): void {
$this->_printGenericOrException(
$level, "print", $content,
@ -428,9 +450,9 @@ class ConsoleMessenger extends AbstractMessenger {
}
function end(bool $all=false): void {
if ($all) $this->_endSection();
elseif ($this->actions) $this->_endAction();
elseif ($this->titles) $this->_endTitle();
else $this->_endSection();
if ($all) $this->section__afterFunc();
elseif ($this->actions) $this->action__end();
elseif ($this->titles) $this->title__end();
else $this->section__afterFunc();
}
}

View File

@ -79,8 +79,16 @@ class LogMessenger extends AbstractMessenger {
return $clone;
}
protected function section__end(): void {
$this->end(true);
}
function section__afterFunc(): void {
$this->section__end();
}
function section($content, ?callable $func=null, ?int $level=null): void {
$this->_endSection();
$this->section__end();
if (!$this->checkLevel($level)) return;
$this->_printTitle(
$this->getLinePrefix(), $level,
@ -90,45 +98,61 @@ class LogMessenger extends AbstractMessenger {
try {
$func($this);
} finally {
$this->_endSection();
$this->section__afterFunc();
}
}
}
function _endSection(): void {
$this->end(true);
}
protected array $titles;
function _getTitleMark(): int {
return count($this->titles);
function title__getMarks(): array {
return [count($this->titles)];
}
function _getTitleId(): ?int {
protected function title__getId(): ?int {
return end($this->titles)["id"] ?? null;
}
protected function title__end(?int $until=null): void {
$title = $this->titles[array_key_last($this->titles)] ?? null;
if ($title !== null) {
$until ??= $title["max_title_level"];
$until ??= $this->title__getMarks()[0] - 1;
while (count($this->titles) > $until) {
array_pop($this->titles);
}
}
}
function title__beforeFunc(array $marks): void {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = $marks[0] + 1;
}
function title__afterFunc(array $marks): void {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = null;
$this->title__end($marks[0]);
}
function title($content, ?callable $func=null, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$titleLevel = $this->_getTitleMark();
$marks = $this->title__getMarks();
$this->titles[] = [
"id" => $this->lastTitleId++,
"title_level" => $titleLevel,
"title_level" => $marks[0],
"max_title_level" => null,
];
$this->_printTitle(
$this->getLinePrefix(), $level,
"title", $content,
$titleLevel, $this->out);
$marks[0], $this->out);
if ($func !== null) {
try {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = $titleLevel + 1;
$this->title__beforeFunc($marks);
$func($this);
} finally {
$title["max_title_level"] = null;
$this->_endTitle($titleLevel);
$this->title__afterFunc($marks);
}
}
}
@ -143,31 +167,47 @@ class LogMessenger extends AbstractMessenger {
}
function _endTitle(?int $until=null): void {
$title = $this->titles[array_key_last($this->titles)];
$until ??= $title["max_title_level"];
$until ??= $this->_getTitleMark() - 1;
while (count($this->titles) > $until) {
array_pop($this->titles);
protected array $actions;
function action__getMarks(): array {
return [count($this->actions)];
}
protected function action__getId(): ?int {
return end($this->actions)["id"] ?? null;
}
protected function action__end(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)] ?? null;
if ($action !== null) {
$until ??= $action["max_action_level"];
$until ??= $this->action__getMarks()[0] - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
}
protected array $actions;
function _getActionMark(): int {
return count($this->actions);
protected function action__flush(bool $endAction=false, ?int $overrideLevel=null): void {
}
function _getActionId(): ?int {
return end($this->actions)["id"] ?? null;
function action__beforeFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = $marks[0] + 1;
}
function action__afterFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = null;
$this->action__end($marks[0]);
}
function action($content, ?callable $func=null, ?int $level=null): void {
$this->checkLevel($level);
$actionLevel = $this->_getActionMark();
$marks = $this->action__getMarks();
$this->actions[] = [
"id" => $this->lastActionId++,
"action_level" => $actionLevel,
"action_level" => $marks[0],
"max_action_level" => null,
"level" => $level
];
@ -175,28 +215,23 @@ class LogMessenger extends AbstractMessenger {
$this->getLinePrefix(), $level,
true, $content,
false, null, null,
$actionLevel, $this->out);
$marks[0], $this->out);
if ($func !== null) {
try {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = $actionLevel + 1;
$this->action__beforeFunc($marks);
$result = $func($this);
if ($this->_getActionMark() > $actionLevel) {
if ($this->action__getMarks()[0] > $marks[0]) {
$this->aresult($result);
}
} catch (Exception $e) {
$this->afailure($e);
throw $e;
} finally {
$action["max_action_level"] = null;
$this->_endAction($actionLevel);
$this->action__afterFunc($marks);
}
}
}
protected function flushActions(bool $endAction=false, ?int $overrideLevel=null): void {
}
function step($content, ?int $level=null): void {
$this->_printGenericOrException(
$level, "step", $content,
@ -204,7 +239,7 @@ class LogMessenger extends AbstractMessenger {
}
function asuccess($content=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null);
if ($this->action__getMarks()[0] == 0) $this->action(null);
$action = end($this->actions);
$level = $overrideLevel ?? $action["level"];
$this->_printAction(
@ -212,11 +247,11 @@ class LogMessenger extends AbstractMessenger {
false, null,
true, true, $content,
$action["action_level"], $this->out);
$this->_endAction();
$this->action__end();
}
function afailure($content=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null);
if ($this->action__getMarks()[0] == 0) $this->action(null);
$action = end($this->actions);
$level = $overrideLevel ?? $action["level"];
$this->_printAction(
@ -224,11 +259,11 @@ class LogMessenger extends AbstractMessenger {
false, null,
true, false, $content,
$action["action_level"], $this->out);
$this->_endAction();
$this->action__end();
}
function adone($content=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null);
if ($this->action__getMarks()[0] == 0) $this->action(null);
$action = end($this->actions);
$level = $overrideLevel ?? $action["level"];
$this->_printAction(
@ -236,26 +271,17 @@ class LogMessenger extends AbstractMessenger {
false, null,
true, null, $content,
$action["action_level"], $this->out);
$this->_endAction();
$this->action__end();
}
function aresult($result=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null);
if ($this->action__getMarks()[0] == 0) $this->action(null);
if ($result === true) $this->asuccess(null, $overrideLevel);
elseif ($result === false) $this->afailure(null, $overrideLevel);
elseif ($result instanceof Exception) $this->afailure($result, $overrideLevel);
else $this->adone($result, $overrideLevel);
}
function _endAction(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)];
$until ??= $action["max_action_level"];
$until ??= $this->_getActionMark() - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
protected function getIndentLevel(bool $withActions=true): int {
$indentLevel = count($this->titles) - 1;
if ($indentLevel < 0) $indentLevel = 0;
@ -296,11 +322,11 @@ class LogMessenger extends AbstractMessenger {
function end(bool $all=false): void {
if ($all) {
while ($this->actions) $this->adone();
while ($this->titles) $this->_endTitle();
while ($this->titles) $this->title__end();
} elseif ($this->actions) {
$this->_endAction();
$this->action__end();
} elseif ($this->titles) {
$this->_endTitle();
$this->title__end();
}
}
}

View File

@ -12,15 +12,18 @@ class NullMessenger implements IMessenger {
}
function section($content, ?callable $func=null, ?int $level=null): void {
if ($func !== null) $func($this);
}
function title($content, ?callable $func=null, ?int $level=null): void {
if ($func !== null) $func($this);
}
function desc($content, ?int $level=null): void {
}
function action($content, ?callable $func=null, ?int $level=null): void {
if ($func !== null) $func($this);
}
function step($content, ?int $level=null): void {

View File

@ -10,14 +10,14 @@ use nulib\output\IMessenger;
* NB: si cette classe est instanciée sans argument, elle agit comme
* {@link NullMessenger}: elle envoie tous les messages vers /dev/null
*/
class ProxyMessenger implements IMessenger {
class ProxyMessenger implements _IMessenger {
function __construct(?IMessenger ...$msgs) {
foreach ($msgs as $msg) {
if ($msg !== null) $this->msgs[] = $msg;
}
}
/** @var IMessenger[] */
/** @var _IMessenger[] */
protected ?array $msgs = [];
function isEmpty(): bool {
@ -43,45 +43,64 @@ class ProxyMessenger implements IMessenger {
return $clone;
}
function section__afterFunc(): void {
foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) {
$msg->section__afterFunc();
}
}
}
function section($content, ?callable $func=null, ?int $level=null): void {
$useFunc = false;
foreach ($this->msgs as $msg) {
$msg->section($content, null, $level);
if ($msg instanceof _IMessenger) $useFunc = true;
}
if ($useFunc && $func !== null) {
if ($func !== null) {
try {
$func($this);
} finally {
/** @var _IMessenger $msg */
foreach ($this->msgs as $msg) {
$msg->_endSection();
}
$this->section__afterFunc();
}
}
}
function title__getMarks(): array {
$marks = [];
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$marks[$key] = $msg->title__getMarks();
}
}
return $marks;
}
function title__beforeFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->title__beforeFunc($marks[$key]);
}
}
}
function title__afterFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->title__afterFunc($marks[$key]);
}
}
}
function title($content, ?callable $func=null, ?int $level=null): void {
$useFunc = false;
$untils = [];
$marks = $this->title__getMarks();
foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) {
$useFunc = true;
$untils[] = $msg->_getTitleMark();
}
$msg->title($content, null, $level);
}
if ($useFunc && $func !== null) {
if ($func !== null) {
try {
$this->title__beforeFunc($marks);
$func($this);
} finally {
/** @var _IMessenger $msg */
$index = 0;
foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) {
$msg->_endTitle($untils[$index++]);
}
}
$this->title__afterFunc($marks);
}
}
}
@ -92,38 +111,43 @@ class ProxyMessenger implements IMessenger {
}
}
function action($content, ?callable $func=null, ?int $level=null): void {
$useFunc = false;
$untils = [];
foreach ($this->msgs as $msg) {
function action__getMarks(): array {
$marks = [];
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$useFunc = true;
$untils[] = $msg->_getActionMark();
$marks[$key] = $msg->action__getMarks();
}
}
return $marks;
}
function action__beforeFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->action__beforeFunc($marks[$key]);
}
}
}
function action__afterFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->action__afterFunc($marks[$key]);
}
}
}
function action($content, ?callable $func=null, ?int $level=null): void {
$marks = $this->action__getMarks();
foreach ($this->msgs as $msg) {
$msg->action($content, null, $level);
}
if ($useFunc && $func !== null) {
if ($func !== null) {
try {
$result = $func($this);
/** @var _IMessenger $msg */
$index = 0;
foreach ($this->msgs as $msg) {
if ($msg->_getActionMark() > $untils[$index++]) {
$msg->aresult($result);
}
}
} catch (Exception $e) {
/** @var _IMessenger $msg */
foreach ($this->msgs as $msg) {
$msg->afailure($e);
}
throw $e;
$this->action__beforeFunc($marks);
$func($this);
} finally {
/** @var _IMessenger $msg */
$index = 0;
foreach ($this->msgs as $msg) {
$msg->_endAction($untils[$index++]);
}
$this->action__afterFunc($marks);
}
}
}

View File

@ -74,17 +74,19 @@ interface _IMessenger extends IMessenger {
"done" => [null, null],
];
function _endSection(): void;
function section__afterFunc(): void;
function _getTitleMark(): int;
/** @return int[] */
function title__getMarks(): array;
/** @param int[] $marks */
function title__beforeFunc(array $marks): void;
/** @param int[] $marks */
function title__afterFunc(array $marks): void;
function _getTitleId(): ?int;
function _endTitle(?int $until=null): void;
function _getActionMark(): int;
function _getActionId(): ?int;
function _endAction(?int $until=null): void;
/** @return int[] */
function action__getMarks(): array;
/** @param int[] $marks */
function action__beforeFunc(array $marks): void;
/** @param int[] $marks */
function action__afterFunc(array $marks): void;
}

1
php/tbin/.gitignore vendored
View File

@ -1,3 +1,4 @@
/devel/
/*.db
/*.cache
/*.log