interface iConnx extends BaseIface {
// LIFECYCLE
function IsOpen() : bool;
function Open() : ActionIface;
function Shut() : ActionIface;
}
trait tConnx {
use BaseTrait;
abstract protected function ActualOpen() : ActionIface;
abstract protected function ActualShut() : ActionIface;
private int $nOpens = 0;
public function IsOpen() : bool { return $this->nOpens > 0; }
private $oAct; // 2025-04-12 For now, this only saves the status of the ActualOpen() operation, not ActualShut().
public function ItWent() : ActionIface { return $this->oAct; }
public function Open() : ActionIface {
$nOpens = $this->nOpens++;
#echo get_called_class()." OPENS: [$nOpens]".CRLF;
if ($nOpens === 0) {
$this->AmHere(' - class: '.get_called_class().' - viewer: '.get_class($this->Inspect()));
$oAct = $this->ActualOpen();
#$this->AmHereShort('OPENED '.$this->Inspect()->Render().' from '.$this->WhoCalledMe());
$this->oAct = $oAct;
} else {
// Report results of actual open, which happened earlier.
$oAct = $this->oAct;
}
return $oAct;
}
public function Shut() : ActionIface {
$nOpens = --$this->nOpens;
$this->AmHereShort("CLOSING: [$nOpens] ".$this->Inspect()->Render());
echo $this->WhoCalledMe();
if ($nOpens === 0) {
// $nOpens just decremented to zero: actually close
#$this->AmHereShort('CLOSING '.$this->Inspect()->Render());
$oAct = $this->ActualShut();
} else {
// 2025-12-03 I suppose *maybe* this should be a SoftAssert()...
self::HardAssert($nOpens >= 0,"Object has received more Shut() requests than Open() requests!");
// $nOpens is still positive: do nothing
$oAct = new ActionClass;
$oAct->SetNoOp();
}
return $oAct;
}
}
abstract class caConnx extends BaseClass implements SelfIface {
use tConnx;
}