From d43d5b71fdefdb618ea3672c718a747eb026bf5c Mon Sep 17 00:00:00 2001 From: Deon George Date: Wed, 2 Oct 2019 15:47:56 +1000 Subject: [PATCH] More work on Edit Frame --- app/Classes/Control.php | 20 ++++++----- app/Classes/Control/EditFrame.php | 18 +++++++++- app/Classes/Control/Test.php | 55 +++++++++++++++++++++++++++++++ app/Classes/Frame.php | 6 ++++ app/Classes/Server.php | 25 +++++++++++--- 5 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 app/Classes/Control/Test.php diff --git a/app/Classes/Control.php b/app/Classes/Control.php index 710eccb..72e1423 100644 --- a/app/Classes/Control.php +++ b/app/Classes/Control.php @@ -8,15 +8,14 @@ use App\Classes\Control\Telnet; abstract class Control { + const prefix = 'App\Classes\Control\'; + // Has this control class finished with input protected $complete = FALSE; // The server object that is running this control class protected $so = NULL; - // The frame applicable for this control (not the current rendered frame, thats in $so) - protected $fo = NULL; - /** * What is the state of the server outside of this control. * Should only contain @@ -27,9 +26,8 @@ abstract class Control */ public $state = []; - public function __construct(Server $so,Frame $fo=NULL) { + public function __construct(Server $so,array $args=[]) { $this->so = $so; - $this->fo = $fo; // Boot control, preparing anything before keyboard entry $this->boot(); @@ -48,11 +46,10 @@ abstract class Control return $this->complete; } - // @todo Change to Dynamic Calls by the existence of files in App\Classes\Control - public static function factory(string $name,Server $so,Frame $fo=NULL) { + public static function factory(string $name,Server $so,array $args=[]) { switch ($name) { case 'editframe': - return new EditFrame($so,$fo); + return new EditFrame($so,$args); case 'register': return new Register($so); @@ -61,7 +58,12 @@ abstract class Control return new Telnet($so); default: - throw new \Exception('Unknown control method: '.$name); + $c = self::prefix.$name; + $o = class_exists($c) ? new $c($so,$args) : FALSE; + + $so->log('debug',sprintf(($o ? 'Executing: %s' : 'Class doesnt exist: %s'),$c)); + + return $o; } } diff --git a/app/Classes/Control/EditFrame.php b/app/Classes/Control/EditFrame.php index 50f91aa..d008fe7 100644 --- a/app/Classes/Control/EditFrame.php +++ b/app/Classes/Control/EditFrame.php @@ -2,8 +2,11 @@ namespace App\Classes\Control; +use Illuminate\Support\Arr; + use App\Classes\Control; -use App\Classes\Parser\Ansi; +use App\Classes\Frame; +use App\Classes\Server; /** * Class Edit Frame handles frame editing @@ -15,6 +18,19 @@ class EditFrame extends Control private $x = 1; private $y = 1; + // The frame applicable for this control (not the current rendered frame, thats in $so) + protected $fo = NULL; + + public function __construct(Server $so,array $args=[]) + { + if (! $args OR ! Arr::get($args,'fo') OR (! $args['fo'] instanceof Frame)) + throw new \Exception('Missing frame to Edit'); + + $this->fo = $args['fo']; + + parent::__construct($so); + } + protected function boot() { // Clear screen and setup edit. diff --git a/app/Classes/Control/Test.php b/app/Classes/Control/Test.php new file mode 100644 index 0000000..cf879ed --- /dev/null +++ b/app/Classes/Control/Test.php @@ -0,0 +1,55 @@ +so->co->send(CLS.HOME.DOWN.CON); + + $this->so->co->send('Press 1, or 2, or 4, 0 to end.'); + } + + public function handle(string $read) + { + switch ($read) + { + case 0: + $this->complete = TRUE; + $read = ''; + break; + + case 1: + $this->so->co->send('You pressed ONE.'); + $read = ''; + break; + + case 2: + $this->so->co->send('You pressed TWO.'); + $read = ''; + break; + + case 3: + $this->so->co->send('You pressed THREE.'); + $read = ''; + break; + + case 4: + $this->so->co->send('You pressed FOUR.'); + $read = ''; + break; + } + + return $read; + } +} \ No newline at end of file diff --git a/app/Classes/Frame.php b/app/Classes/Frame.php index 380635c..45e6318 100644 --- a/app/Classes/Frame.php +++ b/app/Classes/Frame.php @@ -61,6 +61,7 @@ abstract class Frame const FRAMETYPE_ACTION = 'a'; const FRAMETYPE_LOGIN = 'l'; const FRAMETYPE_TERMINATE = 't'; + const FRAMETYPE_EXTERNAL = 'x'; // Fields that are editable // @todo This needs rework. @@ -161,6 +162,11 @@ abstract class Frame return $this->po->char($x,$y); } + public function content(): string + { + return $this->fo->content; + } + /** * Return fields within the frame. */ diff --git a/app/Classes/Server.php b/app/Classes/Server.php index 398066d..fb356ae 100644 --- a/app/Classes/Server.php +++ b/app/Classes/Server.php @@ -184,7 +184,6 @@ abstract class Server { if ($read != '') { if ($read == TCP_IAC) { - // If we are not already in a TELNET LOOP if ($control !== CONTROL_TELNET) { $control = CONTROL_TELNET; @@ -225,8 +224,6 @@ abstract class Server { $action = $save->state['action']; $control = FALSE; } - - dump(sprintf('End: Control is now: %s: Method Count: %s',is_object($control) ? get_class($control) : serialize($control),$method->count())); } printf("- End CONTROL: Read %s (%s): Mode: [%s], Action: [%s], Control: [%s]\n", @@ -446,6 +443,7 @@ abstract class Server { // List of alternate frames has been presented case MODE_WARPTO: + // @todo If we are in a control, we need to terminate it. if (is_numeric($read) AND $read) { $timewarpalt = $alts->get($read-1)->id; $action = ACTION_GOTO; @@ -666,6 +664,7 @@ abstract class Server { // Clear the command, we are finished processing $cmd = ''; + $mode = FALSE; break; } @@ -731,7 +730,7 @@ abstract class Server { } $control = CONTROL_EDIT; - $method->push(Control::factory('editframe',$this,$next_fo)); + $method->push(Control::factory('editframe',$this,['fo'=>$next_fo])); $next_fo = NULL; $method->last()->state['control'] = $control; $method->last()->state['action'] = FALSE; @@ -930,6 +929,24 @@ abstract class Server { break; + // External Frame - run by a control. + case FRAME::FRAMETYPE_EXTERNAL: + $external = explode(' ',$this->fo->content()); + $x = Control::factory(array_shift($external),$this,$external); + + if (! $x) + { + $this->sendBaseline($client,ERR_PAGE); + $mode = $action = FALSE; + break; + } + + $method->push($x); + $control = CONTROL_METHOD; + $action = FALSE; + + break; + // Terminate Frame case Frame::FRAMETYPE_TERMINATE: $client->send($output);