triggerListByPriority; } function __construct(ObjectTrigger ...$triggerList) { if(!$triggerList){ return; } $sorted = true; $maxPriority = ObjectTrigger::PRIORITY_MIN; foreach($triggerList as $trigger){ if(!$this->checkValidTrigger($trigger)){ throw new \InvalidArgumentException('Invalid Trigger Type'); } /** @var ObjectTrigger $trigger */ $priority = $trigger->getPriority(); $uniqueID = $trigger->getUniqueID(); if($sorted){ if($maxPriority < $priority){ $maxPriority = $priority; } else if($maxPriority > $priority){ $sorted = false; } } if(!key_exists($priority, $this->triggerListByPriority)){ $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; continue; } $this->triggerListByPriority[$priority][$uniqueID] = $trigger; } if(!$sorted){ ksort($this->triggerListByPriority); } } function append(ObjectTrigger $trigger):self{ if(!$this->checkValidTrigger($trigger)){ throw new \InvalidArgumentException('Invalid Trigger Type'); } $priority = $trigger->getPriority(); $uniqueID = $trigger->getUniqueID(); if(!$this->triggerListByPriority){ $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; return $this; } $lastKey = array_key_last($this->triggerListByPriority); if($lastKey < $priority){ $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; return $this; } if(key_exists($priority, $this->triggerListByPriority)){ $this->triggerListByPriority[$priority][$uniqueID] = $trigger; } $this->triggerListByPriority[$priority] = [$uniqueID=>$trigger]; ksort($this->triggerListByPriority); return $this; } function merge(?TriggerCaller $other):self{ if($other === null){ return $this; } //NOTE: array_merge로 계속 가야하는가? merge가 많으면 SPL의 LinkedList가 낫지 않나? $newTriggerList = []; $iterLhs = new \ArrayIterator($this->triggerListByPriority); $iterRhs = new \ArrayIterator($other->triggerListByPriority); while($iterLhs->valid() && $iterRhs->valid()){ if($iterLhs->key() < $iterRhs->key()){ $newTriggerList[$iterLhs->key()] = $iterLhs->current(); $iterLhs->next(); continue; } if($iterRhs->key() < $iterLhs->key()){ $newTriggerList[$iterRhs->key()] = $iterRhs->current(); $iterRhs->next(); continue; } $newTriggerList[$iterLhs->key()] = array_merge($iterLhs->current(), $iterRhs->current()); $iterLhs->next(); $iterRhs->next(); } while($iterLhs->valid()){ $newTriggerList[$iterLhs->key()] = $iterLhs->current(); $iterLhs->next(); } while($iterRhs->valid()){ $newTriggerList[$iterRhs->key()] = $iterRhs->current(); $iterRhs->next(); } $this->triggerListByPriority = $newTriggerList; return $this; } function fire(RandUtil $rng, array $env, $arg = null):?array{ foreach($this->triggerListByPriority as $priority=>$subTriggerList){ /** @var ObjectTrigger[] $subTriggerList */ foreach($subTriggerList as $trigger){ $env = $trigger->action($rng, $env, $arg); } } return $env; } }