structure = $structure; $this->lastCombination = 0; return $this; } /** * Generate the next Snowflake ID. */ public function nextId(): int { if (! isset($this->structure)) { throw new \RuntimeException('ID structure is not defined.'); } $id = 0; $sequence = null; foreach ($this->structure->components() as $field) { // Defer sequence until after detecting other-field changes // so we can reset it if needed. if ($field instanceof Sequence) { $sequence = $field; continue; } $current = $field->maxValue() & $field->value(); $id |= $current << $field->offset(); } // The ID variable now holds the combination of all fields except // sequence. Reset the sequence field if any other field has changed. if ($this->lastCombination !== $id) { $sequence?->reset(); } $this->lastCombination = $id; if ($sequence instanceof Sequence) { $id |= ($sequence->maxValue() & $sequence->value()) << $sequence->offset(); } return $id; } }