1. Go to this page and download the library: Download sugarcraft/candy-core library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
sugarcraft / candy-core example snippets
use SugarCraft\Core\{Cmd, KeyType, Model, Msg, Program};
use SugarCraft\Core\Msg\{KeyMsg, WindowSizeMsg};
final class Counter implements Model
{
public function __construct(public readonly int $count = 0) {}
public function init(): ?\Closure { return null; }
public function update(Msg $msg): array
{
if ($msg instanceof KeyMsg) {
return match (true) {
$msg->type === KeyType::Char && $msg->rune === 'q' => [$this, Cmd::quit()],
$msg->type === KeyType::Up => [new self($this->count + 1), null],
$msg->type === KeyType::Down => [new self($this->count - 1), null],
default => [$this, null],
};
}
return [$this, null];
}
public function view(): string { return "count: $this->count\n(↑/↓ to change, q to quit)"; }
}
(new Program(new Counter()))->run();
use SugarCraft\Core\{Kind, Model, Msg, Program, Subscriptions};
use SugarCraft\Core\Cmd\SubscribeCmd;
final class Clock implements Model
{
public function __construct(public readonly int $ticks = 0) {}
public function init(): ?\Closure { return null; }
public function update(Msg $msg): array
{
// tick handling...
return [$this, null];
}
public function view(): string { return "ticks: $this->ticks\n"; }
public function subscriptions(): ?Subscriptions
{
return (new Subscriptions())->withTick('clock-tick', 1.0, fn () => new TickMsg());
}
}
use SugarCraft\Core\{Model, SubscriptionCapable};
final class StaticModel implements Model
{
use SubscriptionCapable;
// ... no subscriptions() needed
}
use SugarCraft\Core\{Cmd, KeyType, Model, Msg, Program, RootModelWithScreenStack, Screen, ScreenStack};
use SugarCraft\Core\Cmd\{PushScreenCmd, PopScreenCmd};
use SugarCraft\Core\Msg\{KeyMsg, ScreenStackPushedMsg, ScreenStackPoppedMsg};
final class DetailScreen implements Model
{
public function __construct(public readonly string $id) {}
public function init(): ?\Closure { return null; }
public function update(Msg $msg): array
{
if ($msg instanceof KeyMsg && $msg->rune === 'b') {
return [$this, Cmd::pop()];
}
return [$this, null];
}
public function view(): string { return "Detail: {$this->id}\n(press b to go back)\n"; }
}
// Root model owns the stack and handles infrastructure messages.
final class App implements Model, \SugarCraft\Core\ScreenStackCapable
{
use \SugarCraft\Core\SubscriptionCapable;
public function __construct(public ScreenStack $screens = new ScreenStack()) {}
public function screens(): ScreenStack { return $this->screens; }
public function init(): ?\Closure { return null; }
public function update(Msg $msg): array
{
if ($msg instanceof ScreenStackPushedMsg) {
return [new self($this->screens->push($msg->screen)), null];
}
if ($msg instanceof ScreenStackPoppedMsg) {
if ($this->screens->isEmpty()) return [$this, null];
$popped = $this->screens->current();
return [new self($this->screens->pop()), null];
}
if ($msg instanceof KeyMsg && $msg->rune === 'n') {
return [$this, new PushScreenCmd(new Screen(new DetailScreen('item-1'), title: 'Item 1'))];
}
return [$this, null];
}
public function view(): string
{
$active = $this->screens->isEmpty()
? new \SugarCraft\Core\Model\Anonymous(fn() => "Push a screen with n\n")
: $this->screens->current()->model;
return $active->view();
}
}
(new Program(new App()))->run();