mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-03-18 05:04:51 +08:00
add timer tick
This commit is contained in:
parent
f03c0940da
commit
df25aebd60
@ -12,13 +12,13 @@
|
||||
`\ZM\Annotation\OneBot\BotCommand` 注解事件类,在经过全局别名后,你也可以使用 `\BotCommand` 作为注解事件,效果相同。
|
||||
|
||||
## 别名列表
|
||||
|
||||
| 全类名 | 别名 |
|
||||
|--------------------------------------------------------|-------------------------|
|
||||
| `\ZM\Annotation\Framework\BindEvent` | `BindEvent` |
|
||||
| `\ZM\Annotation\Framework\Cron` | `Cron` |
|
||||
| `\ZM\Annotation\Framework\Init` | `Init` |
|
||||
| `\ZM\Annotation\Framework\Setup` | `Setup` |
|
||||
| `\ZM\Annotation\Framework\Tick` | `Tick` |
|
||||
| `\ZM\Annotation\Http\Controller` | `Controller` |
|
||||
| `\ZM\Annotation\Http\Route` | `Route` |
|
||||
| `\ZM\Annotation\Middleware\Middleware` | `Middleware` |
|
||||
|
||||
@ -6,6 +6,7 @@ class_alias(\ZM\Annotation\Framework\BindEvent::class, 'BindEvent');
|
||||
class_alias(\ZM\Annotation\Framework\Cron::class, 'Cron');
|
||||
class_alias(\ZM\Annotation\Framework\Init::class, 'Init');
|
||||
class_alias(\ZM\Annotation\Framework\Setup::class, 'Setup');
|
||||
class_alias(\ZM\Annotation\Framework\Tick::class, 'Tick');
|
||||
|
||||
class_alias(\ZM\Annotation\Http\Controller::class, 'Controller');
|
||||
class_alias(\ZM\Annotation\Http\Route::class, 'Route');
|
||||
|
||||
@ -13,6 +13,7 @@ use ZM\Config\ZMConfig;
|
||||
use ZM\Container\ContainerHolder;
|
||||
use ZM\Logger\ConsoleLogger;
|
||||
use ZM\Middleware\MiddlewareHandler;
|
||||
use ZM\Schedule\Timer;
|
||||
use ZM\Store\Database\DBException;
|
||||
use ZM\Store\Database\DBQueryBuilder;
|
||||
use ZM\Store\Database\DBWrapper;
|
||||
@ -55,6 +56,29 @@ function zm_sleep(float|int $time)
|
||||
Adaptive::sleep($time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个计时器(Timer::tick() 的别名)
|
||||
*
|
||||
* @param int $ms 时间(毫秒)
|
||||
* @param callable $callback 回调函数
|
||||
* @param int $times 重复次数(如果为 0 或 -1,则永久循环,其他大于 0 的数为限定次数)
|
||||
*/
|
||||
function zm_timer_tick(int $ms, callable $callback, int $times = 0): int
|
||||
{
|
||||
return Timer::tick($ms, $callback, $times);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个延后一次性计时器,只在指定毫秒后执行一次即销毁(Timer::after() 的别名)
|
||||
*
|
||||
* @param int $ms 时间(毫秒)
|
||||
* @param callable $callback 回调函数
|
||||
*/
|
||||
function zm_timer_after(int $ms, callable $callback): int
|
||||
{
|
||||
return Timer::after($ms, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取协程接口
|
||||
*/
|
||||
|
||||
@ -8,11 +8,13 @@ use Doctrine\Common\Annotations\AnnotationReader;
|
||||
use Koriym\Attributes\AttributeReader;
|
||||
use Koriym\Attributes\DualReader;
|
||||
use ZM\Annotation\Framework\Cron;
|
||||
use ZM\Annotation\Framework\Tick;
|
||||
use ZM\Annotation\Http\Controller;
|
||||
use ZM\Annotation\Http\Route;
|
||||
use ZM\Annotation\Interfaces\ErgodicAnnotation;
|
||||
use ZM\Annotation\Middleware\Middleware;
|
||||
use ZM\Schedule\Schedule;
|
||||
use ZM\Schedule\Timer;
|
||||
use ZM\Store\FileSystem;
|
||||
use ZM\Utils\HttpUtil;
|
||||
|
||||
@ -62,6 +64,7 @@ class AnnotationParser
|
||||
Route::class => [[$this, 'addRouteAnnotation']],
|
||||
Closed::class => [fn () => false],
|
||||
Cron::class => [[resolve(Schedule::class), 'addSchedule']],
|
||||
Tick::class => [[Timer::class, 'registerTick']],
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -240,7 +243,13 @@ class AnnotationParser
|
||||
return $o;
|
||||
}
|
||||
|
||||
public function parseSpecial($annotation, $same_method_annotations = null): ?bool
|
||||
/**
|
||||
* 单独解析特殊注解
|
||||
*
|
||||
* @param object|string $annotation 注解对象
|
||||
* @param null|array $same_method_annotations 相同方法下的其他注解列表(可为数组或 null)
|
||||
*/
|
||||
public function parseSpecial(object|string $annotation, ?array $same_method_annotations = null): ?bool
|
||||
{
|
||||
foreach (($this->special_parsers[$annotation::class] ?? []) as $parser) {
|
||||
$result = $parser($annotation, $same_method_annotations);
|
||||
|
||||
25
src/ZM/Annotation/Framework/Tick.php
Normal file
25
src/ZM/Annotation/Framework/Tick.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Annotation\Framework;
|
||||
|
||||
use Symfony\Contracts\Service\Attribute\Required;
|
||||
use ZM\Annotation\AnnotationBase;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
* @NamedArgumentConstructor()
|
||||
* @Target("METHOD")
|
||||
*/
|
||||
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
|
||||
class Tick extends AnnotationBase
|
||||
{
|
||||
#[Required]
|
||||
public int $tick_ms;
|
||||
|
||||
public function __construct(int $tick_ms, public int $worker_id = 0)
|
||||
{
|
||||
$this->tick_ms = $tick_ms;
|
||||
}
|
||||
}
|
||||
@ -199,14 +199,14 @@ class WorkerEventListener
|
||||
// 从 plugins 目录加载插件,包含 phar 和文件夹形式
|
||||
$count = PluginManager::addPluginsFromDir($load_dir);
|
||||
if ($count !== 0) {
|
||||
logger()->info('Loaded ' . $count . ' user plugins from plugin dir');
|
||||
logger()->debug('已加载 ' . $count . ' 个普通插件');
|
||||
}
|
||||
|
||||
// 从 composer 依赖加载插件
|
||||
if (config('global.plugin.composer_plugin_enable', true)) {
|
||||
$count = PluginManager::addPluginsFromComposer();
|
||||
if ($count !== 0) {
|
||||
logger()->info('Loaded ' . $count . ' user plugins from composer');
|
||||
logger()->info('已加载 ' . $count . ' 个 Composer 插件');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ class Framework
|
||||
public const VERSION_ID = 681;
|
||||
|
||||
/** @var string 版本名称 */
|
||||
public const VERSION = '3.0.0-beta7';
|
||||
public const VERSION = '3.0.0-beta8';
|
||||
|
||||
/** @var array 传入的参数 */
|
||||
protected array $argv;
|
||||
|
||||
@ -208,7 +208,7 @@ class PluginManager
|
||||
foreach (self::$plugins as $name => $meta) {
|
||||
// 除了内建插件外,输出 log 告知启动插件
|
||||
if ($meta->getPluginType() !== ZM_PLUGIN_TYPE_NATIVE) {
|
||||
logger()->info('Enabling plugin: ' . $name);
|
||||
logger()->info('正在启用插件 ' . $name);
|
||||
}
|
||||
// 先判断依赖关系,如果声明了依赖,但依赖不合规则报错崩溃
|
||||
foreach ($meta->getDependencies() as $dep_name => $dep_version) {
|
||||
@ -257,6 +257,11 @@ class PluginManager
|
||||
foreach ($entity->getInits() as $init) {
|
||||
AnnotationMap::addSingleAnnotation($init);
|
||||
}
|
||||
// 设置 TimerTick 注解
|
||||
foreach ($entity->getTimerTicks() as $tick) {
|
||||
AnnotationMap::addSingleAnnotation($tick);
|
||||
$parser->parseSpecial($tick);
|
||||
}
|
||||
}
|
||||
// 如果设置了 Autoload file,那么将会把 psr-4 的加载路径丢进 parser
|
||||
foreach ($meta->getAutoloadPsr4() as $namespace => $path) {
|
||||
|
||||
29
src/ZM/Plugin/Traits/TickTrait.php
Normal file
29
src/ZM/Plugin/Traits/TickTrait.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Plugin\Traits;
|
||||
|
||||
use ZM\Annotation\Framework\Tick;
|
||||
|
||||
trait TickTrait
|
||||
{
|
||||
protected array $ticks = [];
|
||||
|
||||
public function addTimerTick(int $ms, callable $callback, int $worker_id = 0): void
|
||||
{
|
||||
$tick = new Tick($ms, $worker_id);
|
||||
if (is_array($callback)) {
|
||||
$tick->class = $callback[0];
|
||||
$tick->method = $callback[1];
|
||||
} elseif ($callback instanceof \Closure) {
|
||||
$tick->method = $callback;
|
||||
}
|
||||
$this->ticks[] = $tick;
|
||||
}
|
||||
|
||||
public function getTimerTicks(): array
|
||||
{
|
||||
return $this->ticks;
|
||||
}
|
||||
}
|
||||
@ -18,4 +18,5 @@ class ZMPlugin
|
||||
use Traits\PluginLoadTrait;
|
||||
use Traits\RouteTrait;
|
||||
use Traits\PluginPackTrait;
|
||||
use Traits\TickTrait;
|
||||
}
|
||||
|
||||
32
src/ZM/Schedule/Timer.php
Normal file
32
src/ZM/Schedule/Timer.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Schedule;
|
||||
|
||||
use ZM\Annotation\Framework\Tick;
|
||||
use ZM\Framework;
|
||||
|
||||
class Timer
|
||||
{
|
||||
public static function tick(int $ms, callable $callback, int $times = 0): int
|
||||
{
|
||||
return Framework::getInstance()->getDriver()->getEventLoop()->addTimer($ms, $callback, $times);
|
||||
}
|
||||
|
||||
public static function after(int $ms, callable $callback): int
|
||||
{
|
||||
return Framework::getInstance()->getDriver()->getEventLoop()->addTimer($ms, $callback);
|
||||
}
|
||||
|
||||
public static function registerTick(Tick $v): void
|
||||
{
|
||||
if ($v->class !== '' && $v->method !== '') {
|
||||
self::tick($v->tick_ms, [resolve($v->class), $v->method]);
|
||||
} elseif (is_callable($v->method)) {
|
||||
self::tick($v->tick_ms, $v->method);
|
||||
} else {
|
||||
logger()->warning('注册的 Tick 定时器回调函数错误');
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user