Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Last active September 16, 2015 17:09
Show Gist options
  • Save mindplay-dk/7e069891ab8881d8dfba to your computer and use it in GitHub Desktop.
Save mindplay-dk/7e069891ab8881d8dfba to your computer and use it in GitHub Desktop.
Typescript event hook and hookable boxed value classes
/// This interface defines an event listener
interface Listener<Event> {
(event: Event): void
}
/// This interface represents a hookable type
interface Hookable<Event> {
/// Attach a handler to this hookable
(handler: Listener<Event>): void
}
/// This interface represents an event hook
interface Hook<Event> extends Hookable<Event> {
/// Send an event to all listeners
(event: Event): void
or<Other>(another: Hook<Other>) : Hookable<Event|Other>
}
/// This interface represents a hookable boxed value
interface Box<T> extends Hook<T> {
/// Retrieve the value
() : T
}
function chain() {
// TODO
}
/// Create an event hook for a specific type of message
function hook<Event>(): Hook<Event> {
var _handlers: Array<Function> = []
var _busy = false
function invoke() {
if (arguments[0] instanceof Function) {
_handlers.push(arguments[0])
} else if (!_busy) {
_busy = true
for (var i = 0; i < _handlers.length; i++) {
_handlers[i].apply(this, arguments)
}
_busy = false
}
}
invoke["or"] = chain
return <Hook<Event>> <any> invoke
}
/// Create a hookable boxed value (optionally with an initial value)
function box<T>(value?: T): Box<T> {
var _value: T = value
var _handlers: Array<Function> = []
var _busy = false
function invoke() {
if (arguments.length === 0) {
return _value
} else if (arguments[0] instanceof Function) {
_handlers.push(arguments[0])
} else if (!_busy) {
_value = arguments[0]
_busy = true
for (var i = 0; i < _handlers.length; i++) {
_handlers[i].apply(this, arguments)
}
_busy = false
}
}
return <Box<T>> invoke
}
// EXAMPLE:
class User
{
first_name = box("Rasmus")
last_name = box("Schultz")
}
var u = new User()
//u.first_name(name => console.log("Logged in: " + name))
u.first_name.or(u.last_name)((value) => console.log(value))
u.first_name("Rasmus")
u.last_name("Schultz")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment