Initialize Nest events library.

This commit is contained in:
Madeorsk 2024-11-08 15:59:15 +01:00
commit fcb3e114a7
Signed by: Madeorsk
GPG key ID: 677E51CA765BB79F
6 changed files with 216 additions and 0 deletions

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
# IDEA
.idea/
*.iml
# Composer
vendor/

27
composer.json Normal file
View 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
View 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
View file

@ -0,0 +1,7 @@
<?php
namespace Nest\Events;
abstract class Event
{
}

81
src/EventsManager.php Normal file
View 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
View 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);
}
}