Skip to content

Commit

Permalink
use msgpack
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <georgelemon@protonmail.com>
  • Loading branch information
georgelemon committed Apr 11, 2024
1 parent 0708559 commit 3cff217
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 36 deletions.
5 changes: 3 additions & 2 deletions emitter.nimble
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Package

version = "0.1.1"
author = "George Lemon"
description = "Supranim's Event Emitter - Subscribe & listen for various events within your application"
author = "Supranim"
description = "Supranim's Event Emitter - Subscribe & listen for events"
license = "MIT"
srcDir = "src"

Expand All @@ -11,6 +11,7 @@ srcDir = "src"

requires "nim >= 1.4.0"
requires "malebolgia#head"
requires "msgpack4nim"

task docgen, "Generate API documentation":
exec "nim doc --project --index:on --outdir:htmldocs src/emitter.nim"
Expand Down
64 changes: 30 additions & 34 deletions src/emitter.nim
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# Supranim's Event Emitter - Subscribe & listen for
# various events within your application.
#
# (c) 2021 Events is released under MIT License
# Made by Humans from OpenPeep
# (c) 2024 Events is released under MIT License
# Made by Humans from OpenPeeps
#
# https://github.com/supranim
# https://supranim.com

import std/[tables, sequtils, macros, typeinfo]
from std/strutils import count, startsWith

# import std/threadpool
import std/[tables, strutils, sequtils, macros, typeinfo]
import pkg/msgpack4nim
# import pkg/malebolgia

export tables, typeinfo
Expand All @@ -19,10 +17,8 @@ type
RunType* = enum
Anytime, Once

Arg* = ref object
value*: Any

Callback* = proc(args: seq[Arg]) {.nimcall.}
Args* = seq[string]
Callback* = proc(args: Args) {.nimcall.}

Listener* = tuple[id: string, runCallable: Callback, runType: RunType]

Expand All @@ -32,7 +28,6 @@ type
subscribers: Table[string, seq[Listener]]
# m: Master


EventEmitterError = object of CatchableError

# when compileOption("threads"):
Expand All @@ -43,17 +38,20 @@ var Event*: EventEmitter
proc init*(e: var EventEmitter) =
Event = EventEmitter()

template newArg*(argValue: auto): untyped =
## Create a new Arg object instance based on
## ``Any`` value from ``std/typeinfo``
var
vany: Any
val = argValue
proc initNewArg(v: Any): Arg =
return Arg(value: v)
vany = toAny(val)
initNewArg(vany)
proc newArg*(arg: string): string =
## Packs a new string `arg` via MsgPack
result = pack(arg)

proc newArg*(arg: int): string =
## Packs a new int `arg` via MsgPack
result = pack(arg).stringify

proc newArg*(arg: float): string =
## Packs a new float `arg` via MsgPack
result = pack(arg).stringify

proc unpackArg*(x: string): string =
unpack(x, result)

proc registerListener(emitter: var EventEmitter, key: string, handler: Callback, runType: RunType) =
## Main proc for registering listeners to a specific events by ``key``.
Expand All @@ -67,37 +65,35 @@ proc registerListener(emitter: var EventEmitter, key: string, handler: Callback,
proc listen*(emitter: var EventEmitter, key: string, handler: Callback) =
## Subscribe to a specific event with a runnable callback.
##
## You may want to register a listener using the ``*``
## as a wildcard for ``key`` parameter. This allows you to
## register same listener to multiple events.
## Use wildcard `*` to register the same listener
## to multiple events
runnableExamples:
Event.listen("account.update.email") do(args: seq[Arg]):
Event.listen("account.update.email") do(args: Args):
echo "Email address has been changed."

Event.listen("account.*") do(args: seq[Arg]):
Event.listen("account.*") do(args: Args):
echo "Listening for any events related to `account.`"

registerListener(emitter, key, handler, Anytime)

template listenOnce*(emitter: var EventEmitter, key: string, handler: Callback) =
## Same as ``listen`` proc, the only difference is
## Same as `listen` proc, the only difference is
## that this listener can run only once
registerListener(emitter, key, handler, Once)

proc runCallback(args: ptr seq[Arg], listen: ptr Listener) =
proc runCallback(args: ptr Args, listen: ptr Listener) =
{.gcsafe.}:
listen[].runCallable(@[])
listen[].runCallable(args[])

proc emit*(emitter: var EventEmitter, eventId: string, args: seq[Arg] = @[]) =
## Call an event by ``id`` and trigger all registered listeners
## related to the event. You can pass one or more ``args``
## to listener callback using the ``newArg`` procedure.
proc emit*(emitter: var EventEmitter, eventId: string, args: Args = @[]) =
## Call an event by `id` and trigger all registered listeners
## related to the event. You can pass one or more `args`
## to listener callback using the `newArg` procedure.
runnableExamples:
Event.emit("account.update.email", newArg("new.address@example.com"), newArg("192.168.1.1"))
if emitter.subscribers.hasKey(eventId):
for i, listener in pairs(emitter.subscribers[eventId]):
let x = args
# spawn runCallback(x.addr, listener.addr)
runCallback(x.addr, listener.addr)
if likely(listener.runType == Once):
emitter.subscribers[eventId].delete(i)
Expand Down

0 comments on commit 3cff217

Please sign in to comment.