__context = UUID::normalize($__context); $this->__super = UUID::normalize($__super); $G = &self::$__gc[$this->__super][get_called_class()][$this->__context]; $this->__Definition = &$G[0x00]; $this->__clsid = &$G[0x01]; #+ create data matrix: $this->__Data instanceOf Data ?: $this->__Data = new Data; #+ load or create type declaration for this class if(NULL === ($T = &$G[0x00])) $T = new GC((array) $__type); #+ set property flag by type declaration switch(TRUE): case 0x00 === $T->getSize(): $this->__prop |= __flag_T::T_VOID; break; case 0x01 === $T->getSize(): $this->__prop |= __flag_T::T_SHALLOW; break; case 0x02 === $T->getSize(): $this->__prop |= __flag_T::T_PAIR; break; case 0x02 < $T->getSize(): $this->__prop |= __flag_T::T_ROW; break; endswitch; foreach(class_implements($this) as $interface) switch($interface): case IListable::class: $this->__prop |= __flag_T::T_LISTABLE; break; case ILimitable::class: $this->__prop |= __flag_T::T_LIMITABLE; break; endswitch; #+ set matrix dimension switch(TRUE): case $this instanceOf IListable: $this->__Data->setSize($T->getSize()); break; case 0x00 === $T->getSize(): $this->__Data->setDimension(0x00, 0x00); break; case 0x00 < $T->getSize(): $this->__Data->setDimension($T->getSize(), 0x01); break; endswitch; #+ clsid NULL !== ($C = &$G[0x01]) ?: $C = (new Clsid(__CLASS__, get_called_class(), [ 'definition' => $T->invoke('invoke', ['clsid']), // Fsc->Fsc->Define::clsid() 'prop' => $this->__prop ], $this->__context, $this->__super))->uuid(); } /** * add or remove lines in data FSM * * @param int $__length Lines : y range * @throws Exception when interface T_LISTABLE is not implemented * @throws Exception when interface T_LIMITABLE is implemented */ function setLength($__length) { if(__flag_T::T_LISTABLE !== ($this->__prop & __flag_T::T_LISTABLE) || __flag_T::T_LIMITABLE === ($this->__prop & __flag_T::T_LIMITABLE)) throw new Exception('Unable to add or remove lines (y offset): {:class} does not implement interface {:IListable} or implements {:ILimitable}.', ['class' => get_called_class(), 'ILimitable' => ILimitable::class, 'IListable' => IListable::class]); $this->__Data->setLength($__length); return $this; } function inRange($__field = 0x00, $__line = 0x00) { return $__field >= 0x00 && $__line >= 0x00 && $__field <= $this->__Data->getSize() - 1 && $__line <= $this->__Data->getLength() - 1; } /** * store value at specific offset in data FSM * * n = 0 ... defined fields - 1 * i = 0 ... infinite * f = 0 ... finite * * T T T * * & T_PAIR [0,0] [1,0] [0,i] [1,i] [0,f] [1,f] * & T_ROW [n,0] [n,i] [n,f] * & T_SHALLOW [0,0] [0,i] [0,f] * * @param mixed $__value expected type is defined in Field Declaration * @param int $__field Field : offset x, default 0 * @param int $__line Line : offset y, default 0 * * @internal this method should be protected * @testing default address for $__prop * @todo */ function set($__value, $__field = 0x00, $__line = 0x00) { if(FALSE === $this->inRange($__field, $__line)) throw new Exception('Unable to set data: address {:class} not found.', ['field' => $__field, 'line' => $__line, 'class' => get_called_class()]); $this->__Data->offsetGet($__field)->offsetSet($__line, $__value); }