mirror of
https://github.com/flynx/types.js.git
synced 2025-12-19 09:51:40 +00:00
refactoring and fixes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
b164450c0f
commit
cce5eaf1e7
89
event.js
89
event.js
@ -18,6 +18,14 @@ var object = require('ig-object')
|
||||
/*********************************************************************/
|
||||
// Event method wrappers...
|
||||
|
||||
var EventCommand =
|
||||
module.EventCommand =
|
||||
object.Constructor('EventCommand', {
|
||||
name: null,
|
||||
__init__: function(name, data={}){
|
||||
Object.assign(this, data, {name}) },
|
||||
})
|
||||
|
||||
// Create an "eventfull" method...
|
||||
//
|
||||
// The resulting method can be either called directly or via .trigger(..).
|
||||
@ -32,6 +40,7 @@ var object = require('ig-object')
|
||||
// -> method
|
||||
//
|
||||
//
|
||||
// Trigger the event...
|
||||
// method(...args)
|
||||
// -> ..
|
||||
//
|
||||
@ -40,6 +49,35 @@ var object = require('ig-object')
|
||||
// -> ..
|
||||
//
|
||||
//
|
||||
// trigger event handlers...
|
||||
// handle()
|
||||
// handle(true)
|
||||
// -> true
|
||||
// -> false
|
||||
//
|
||||
// prevent event handlers from triggering...
|
||||
// handle(false)
|
||||
// -> undefined
|
||||
//
|
||||
//
|
||||
//
|
||||
// Special case: EventCommand...
|
||||
//
|
||||
// EventCommand instance can be passed as the first argument of method,
|
||||
// in this case the event function will get it but the event handlers
|
||||
// will not...
|
||||
// This is done to be able to externally pass commands to event methods
|
||||
// that get handled in a special way by the function but not passed to
|
||||
// the event handlers...
|
||||
//
|
||||
// method(<event-command>, ...args)
|
||||
// -> ..
|
||||
//
|
||||
// func(handle, <event-command>, ...args)
|
||||
// -> ..
|
||||
//
|
||||
//
|
||||
//
|
||||
// NOTE: calling handle(false) will exiplicitly disable calling the
|
||||
// handlers for that call...
|
||||
var Eventfull =
|
||||
@ -69,17 +107,18 @@ function(name, func, options={}){
|
||||
// after the event action is done but before it returns...
|
||||
// NOTE: to explicitly disable calling the handlers func must
|
||||
// call handle(false)
|
||||
// XXX should he user be able to control the args passed to
|
||||
// the handlers???
|
||||
var did_handle = false
|
||||
var handle = function(skip=false){
|
||||
did_handle = skip === true
|
||||
return skip ?
|
||||
undefined
|
||||
: handlers
|
||||
var handle = function(run=true){
|
||||
did_handle = run === false
|
||||
var a = args[0] instanceof EventCommand ?
|
||||
args.slice(1)
|
||||
: args
|
||||
return run ?
|
||||
handlers
|
||||
.reduce(function(res, handler){
|
||||
return res === true
|
||||
&& handler(name, ...args) !== false }, true) }
|
||||
&& handler(name, ...a) !== false }, true)
|
||||
: undefined }
|
||||
|
||||
var res = func ?
|
||||
func.call(this, handle, ...args)
|
||||
@ -142,7 +181,8 @@ function(name, func, options={}){
|
||||
return method }
|
||||
|
||||
|
||||
module.TRIGGER = {doc: 'force event method to trigger'}
|
||||
|
||||
module.TRIGGER = module.EventCommand('TRIGGER')
|
||||
|
||||
// Extends Eventfull(..) adding ability to bind events via the
|
||||
// resulting method directly by passing it a function...
|
||||
@ -179,9 +219,6 @@ module.TRIGGER = {doc: 'force event method to trigger'}
|
||||
// This will pass args to the event action regardless whether the first
|
||||
// arg is a function or not...
|
||||
//
|
||||
//
|
||||
// XXX might be a good idea to adde an event that can't be triggered by
|
||||
// calling...
|
||||
var Event =
|
||||
module.Event =
|
||||
function(name, func, options={}){
|
||||
@ -194,18 +231,14 @@ function(name, func, options={}){
|
||||
return object.mixin(
|
||||
method = Eventfull(name,
|
||||
function(handle, ...args){
|
||||
// add handler...
|
||||
if(typeof(args[0]) == 'function'){
|
||||
// NOTE: when the first arg is an event command this will
|
||||
// fall through to calling the action...
|
||||
typeof(args[0]) == 'function' ?
|
||||
// add handler...
|
||||
method.__event_handler_add__(this, args[0])
|
||||
|
||||
// call the action...
|
||||
} else {
|
||||
// special case: force trigger -> remove TRIGGER from args...
|
||||
args[0] === module.TRIGGER
|
||||
&& args.shift()
|
||||
func
|
||||
&& func.call(this, handle, ...args) }
|
||||
|
||||
// call the action...
|
||||
: (func
|
||||
&& func.call(this, handle, ...args))
|
||||
return this },
|
||||
options),
|
||||
{
|
||||
@ -220,6 +253,16 @@ function(name, func, options={}){
|
||||
}) }
|
||||
|
||||
|
||||
// Like Event(..) but produces an event that can only be triggered via
|
||||
// .trigger(name, ...), calling this is a no-op...
|
||||
var PureEvent =
|
||||
module.PureEvent =
|
||||
function(name, options={}){
|
||||
return Event(name, function(handle, trigger){
|
||||
trigger === module.TRIGGER
|
||||
|| handle(false) }, options)}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Mixins...
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-types",
|
||||
"version": "5.0.9",
|
||||
"version": "5.0.10",
|
||||
"description": "Generic JavaScript types and type extensions...",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
||||
55
runner.js
55
runner.js
@ -337,6 +337,38 @@ object.Mixin('TaskMixin', 'soft', {
|
||||
})
|
||||
|
||||
|
||||
// Make the ticket more usable...
|
||||
var TaskTicket =
|
||||
module.TaskTicket =
|
||||
object.Constructor('TaskTicket', {
|
||||
__data: null,
|
||||
|
||||
title: null,
|
||||
|
||||
resolve: function(...args){
|
||||
this.__data.resolve(...args)
|
||||
return this },
|
||||
reject: function(...args){
|
||||
this.__data.reject(...args)
|
||||
return this },
|
||||
onmessage: function(msg, func){
|
||||
this.__data.onmessage(
|
||||
typeof(msg) == 'function' ?
|
||||
msg
|
||||
: function(m, ...args){
|
||||
m == msg
|
||||
&& func(...args) })
|
||||
return this },
|
||||
|
||||
__init__: function(title, resolve, reject, onmessage){
|
||||
this.title = title
|
||||
Object.defineProperty(this, '__data', {
|
||||
__data: {resolve, reject, onmessage},
|
||||
enumerable: false,
|
||||
}) },
|
||||
})
|
||||
|
||||
|
||||
// XXX we should keep the API here similar to Queue...
|
||||
// ...but this is no a queue in principle (internal vs. external
|
||||
// management) so we'll also need to keep them different enough to
|
||||
@ -359,6 +391,8 @@ object.Constructor('TaskManager', Array, events.EventMixin('flat', {
|
||||
.filter(function(task){
|
||||
return titles.has(task.title) }) },
|
||||
|
||||
// actions...
|
||||
//
|
||||
send: function(title, ...args){
|
||||
if(title == 'all' || title == '*'){
|
||||
this.forEach(function(task){
|
||||
@ -369,7 +403,6 @@ object.Constructor('TaskManager', Array, events.EventMixin('flat', {
|
||||
title
|
||||
: [title])
|
||||
.send('all', ...args) },
|
||||
|
||||
// XXX each task should also trigger this when stopping and this
|
||||
// should not result in this and tasks infinitely playing
|
||||
// ping-pong...
|
||||
@ -380,8 +413,11 @@ object.Constructor('TaskManager', Array, events.EventMixin('flat', {
|
||||
function(handlers, title='all'){
|
||||
this.send(title, 'stop') }),
|
||||
|
||||
done: events.Event('done'),
|
||||
error: events.Event('error'),
|
||||
// events...
|
||||
//
|
||||
done: events.PureEvent('done'),
|
||||
tasksDone: events.PureEvent('tasksDone'),
|
||||
error: events.PureEvent('error'),
|
||||
|
||||
|
||||
//
|
||||
@ -416,10 +452,6 @@ object.Constructor('TaskManager', Array, events.EventMixin('flat', {
|
||||
//
|
||||
// NOTE: the args are passed only if
|
||||
// NOTE: the task is started as soon as it is accepted.
|
||||
//
|
||||
// XXX seems that we have a dangling promise someplace...
|
||||
// ...if a task rejects node/chrome report an unhandled promise
|
||||
// reject...
|
||||
Task: function(title, task, ...args){
|
||||
var that = this
|
||||
|
||||
@ -461,12 +493,9 @@ object.Constructor('TaskManager', Array, events.EventMixin('flat', {
|
||||
// the context is ready...
|
||||
run = function(){
|
||||
var res =
|
||||
task({
|
||||
title,
|
||||
resolve,
|
||||
reject,
|
||||
onmessage,
|
||||
}, ...args)
|
||||
task(
|
||||
TaskTicket(title, resolve, reject, onmessage),
|
||||
...args)
|
||||
// NOTE: if the client calls resolve(..) this
|
||||
// second resolve(..) call has no effect,
|
||||
// and the same is true with reject...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user