Initialize Nest events library.
This commit is contained in:
commit
fcb3e114a7
6 changed files with 216 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
# IDEA
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# Composer
|
||||
vendor/
|
27
composer.json
Normal file
27
composer.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"version": "1.0",
|
||||
"name": "nest/events",
|
||||
"description": "Nest events implementation.",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Madeorsk",
|
||||
"email": "madeorsk@protonmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Nest\\Events\\": "src/"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://code.zeptotech.net/Nest/Core"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.3",
|
||||
"nest/core": "dev-main"
|
||||
}
|
||||
}
|
56
composer.lock
generated
Normal file
56
composer.lock
generated
Normal file
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4185bcac56ba1943814494a50cebd442",
|
||||
"packages": [
|
||||
{
|
||||
"name": "nest/core",
|
||||
"version": "dev-main",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://code.zeptotech.net/Nest/Core",
|
||||
"reference": "22296b8d7c8b528089189a8d9500395424cb6468"
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.3"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Nest\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/Utils/Array.php",
|
||||
"src/Utils/Paths.php",
|
||||
"src/Utils/Reflection.php",
|
||||
"src/Utils/String.php"
|
||||
]
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Madeorsk",
|
||||
"email": "madeorsk@protonmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Nest framework core.",
|
||||
"time": "2024-11-08T11:12:38+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"nest/core": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^8.3"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
7
src/Event.php
Normal file
7
src/Event.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Nest\Events;
|
||||
|
||||
abstract class Event
|
||||
{
|
||||
}
|
81
src/EventsManager.php
Normal file
81
src/EventsManager.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Nest\Events;
|
||||
|
||||
use Nest\Exceptions\InvalidTypeException;
|
||||
use function Nest\Utils\expect_type;
|
||||
use function Nest\Utils\get_all_classes;
|
||||
|
||||
/**
|
||||
* Events manager class.
|
||||
*/
|
||||
class EventsManager
|
||||
{
|
||||
/**
|
||||
* Events listeners.
|
||||
* If false is returned, stop event propagation.
|
||||
* @var array<class-string, (callable(Event $event): (void|bool))[]>
|
||||
*/
|
||||
protected array $listeners = [];
|
||||
|
||||
/**
|
||||
* Add an event listener to the listeners list.
|
||||
* @template T of Event
|
||||
* @param class-string<T> $eventType The event type class to listen for.
|
||||
* @param callable(T $event): (void|bool) $listener The event listener to add. If false is returned, stop event propagation.
|
||||
* @return void
|
||||
* @throws InvalidTypeException
|
||||
*/
|
||||
public function addListener(string $eventType, callable $listener): void
|
||||
{
|
||||
expect_type($eventType, Event::class);
|
||||
|
||||
// Initialize the listeners list if it's empty.
|
||||
if (empty($this->listeners[$eventType])) $this->listeners[$eventType] = [];
|
||||
// Add the listener.
|
||||
$this->listeners[$eventType][] = $listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given listener from the listeners list.
|
||||
* @template T of Event
|
||||
* @param class-string<T> $eventType The event type class.
|
||||
* @param callable(T $event): (void|bool) $listener The listener to remove.
|
||||
* @return void
|
||||
* @throws InvalidTypeException
|
||||
*/
|
||||
public function removeListener(string $eventType, callable $listener): void
|
||||
{
|
||||
expect_type($eventType, Event::class);
|
||||
|
||||
if (!empty($this->listeners[$eventType]))
|
||||
{
|
||||
foreach ($this->listeners[$eventType] as $key => $currentListener)
|
||||
{ // For each listeners, if it's matching the given one, remove it.
|
||||
if ($currentListener == $listener) unset($this->listeners[$eventType][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event.
|
||||
* @param Event $event The event to fire.
|
||||
* @return void
|
||||
*/
|
||||
public function fire(Event $event): void
|
||||
{
|
||||
foreach (get_all_classes($event) as $className)
|
||||
{ // For each class, from the most specific to the least specific.
|
||||
if (!empty($this->listeners[$className]))
|
||||
{ // If there are listeners for the current class.
|
||||
foreach ($this->listeners[$className] as $listener)
|
||||
{ // Call each listener.
|
||||
$result = $listener($event);
|
||||
if ($result === false)
|
||||
// If the result is false, stop firing.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
src/HasEvents.php
Normal file
39
src/HasEvents.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Nest\Events;
|
||||
|
||||
use Nest\Exceptions\InvalidTypeException;
|
||||
|
||||
trait HasEvents
|
||||
{
|
||||
/**
|
||||
* Events manager instance.
|
||||
* @var EventsManager
|
||||
*/
|
||||
private EventsManager $eventsManager;
|
||||
|
||||
/**
|
||||
* Get the current instance of the events manager.
|
||||
* @return EventsManager - The events manager.
|
||||
*/
|
||||
protected function getEventsManager(): EventsManager
|
||||
{
|
||||
// If there is no instance, initializing one.
|
||||
if (empty($this->eventsManager)) $this->eventsManager = new EventsManager();
|
||||
|
||||
return $this->eventsManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for the given event type.
|
||||
* @template T of Event
|
||||
* @param class-string<T> $eventType The event type class to listen for.
|
||||
* @param callable(T $event): (void|bool) $eventListener The event listener. If false is returned, stop event propagation.
|
||||
* @return void
|
||||
* @throws InvalidTypeException
|
||||
*/
|
||||
public function listen(string $eventType, callable $eventListener): void
|
||||
{
|
||||
$this->getEventsManager()->addListener($eventType, $eventListener);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue