Implement @softDepend annotation for event handlers - skip registering if the event class is undefined (#2162)

This allows plugins to soft-depend on other plugins without separating their listeners into a dedicated class for listening to that plugin.

This can be utilized by adding a `@softDepend PluginName` to the event handler's annotations.
If the plugin providing the event does not exist or is not loaded, then the handler will silently not be registered.
If it does exist and the event is not found, the original behaviour applies and an exception will be thrown.

This change should be fully backwards compatible.
This commit is contained in:
SOFe 2018-05-01 21:33:24 +08:00 committed by Dylan K. Taylor
parent d8f4dde5f3
commit 3293074cfc

View File

@ -35,6 +35,8 @@ use pocketmine\permission\Permission;
use pocketmine\Server;
use pocketmine\timings\Timings;
use pocketmine\timings\TimingsHandler;
use pocketmine\utils\MainLogger;
use pocketmine\utils\TextFormat;
/**
* Manages all the plugins, Permissions and Permissibles
@ -752,7 +754,17 @@ class PluginManager{
$ignoreCancelled = isset($tags["ignoreCancelled"]) && strtolower($tags["ignoreCancelled"]) === "true";
$parameters = $method->getParameters();
if(count($parameters) === 1 and $parameters[0]->getClass() instanceof \ReflectionClass and is_subclass_of($parameters[0]->getClass()->getName(), Event::class)){
try{
$isHandler = count($parameters) === 1 && $parameters[0]->getClass() instanceof \ReflectionClass && is_subclass_of($parameters[0]->getClass()->getName(), Event::class);
}catch(\ReflectionException $e){
if(isset($tags["softDepend"]) && !isset($this->plugins[$tags["softDepend"]])){
MainLogger::getLogger()->debug("Not registering @softDepend listener " . get_class($listener) . "::" . $method->getName() . "(" . $parameters[0]->getType()->getName() . ") because plugin \"" . $tags["softDepend"] . "\" not found");
continue;
}
throw $e;
}
if($isHandler){
$class = $parameters[0]->getClass()->getName();
$this->registerEvent($class, $listener, $priority, new MethodEventExecutor($method->getName()), $plugin, $ignoreCancelled);
}