0.0.4 • Published 6 years ago
slot-signal v0.0.4
Slot-Signal
Signal/Slot pattern implemented in pure ES6+.
No dependency, small and efficient library. We try to follow the Qt syntax for the connection, i.e., connect(emitter, signal, receiver, slot)
.
Slot can be any method from a class, a setter or any function with any number of arguments.
This lib provides 4 ways to perform connections
- connect(emitter, signalName, receiver, slotName)
- connect(emitter, signalName, receiver.method)
- connect(emitter, signalName, function)
- connect(emitter, signalName, arrow-function)
Install
npm i slot-signal
Testing
Go inside node_module/slot-signal
and run npm run ex1
or npm run ex2
Usage
Importing the package
import {createSignal, emit, connect} from 'slot-signal'
Create your signals by calling (can be done in the constructor of a class):
createSignal(emitter, signalName)
Connect your objects in two ways
connect(emitter, signalName, receiver, slotName)
connect(emitter, signalName, function)
Then, emitting a signal is simple
emit(emitter, signalName, args)
Example 1
import {createSignal, emit, connect} from 'slot-signal'
class Counter {
constructor() {
this._value = 0
createSignal(this, 'valueChanged')
}
get value() {
return this._value
}
// Slot Setter
set value(value) { // slot
if (value != this._value) {
this._value = value
emit(this, 'valueChanged', value)
}
}
// Slot Arrow
showDouble = () => {
console.log(`2*${this._value} = ${2*this._value}`)
}
// Slot Method
showTripple() {
console.log(`3*${this._value} = ${3*this._value}`)
}
// Slot multiple arguments
setParams(a,b,c) {
console.log(`method with 3 params: a=${a} b=${b} c=${c}`)
}
}
const a = new Counter()
const b = new Counter()
createSignal(b, 'paramsChanged')
connect(a, 'valueChanged', b, 'value')
connect(a, 'valueChanged', v => console.log('Value of a changed to', v) )
connect(b, 'valueChanged', v => console.log('Value of b changed to', v) )
connect(b, 'valueChanged', b, 'showDouble')
connect(b, 'valueChanged', b, 'showTripple')
connect(b, 'paramsChanged', b, 'setParams')
a.value = 12
b.value = 48
a.value = 12 // does not trigger anything since the value is the same
emit(b, 'paramsChanged', 1, 2, 3) // another way of emitting
will display
Value of b changed to 12
2*12 = 12
3*12 = 36
Value of a changed to 12
Value of b changed to 48
2*48 = 96
3*48 = 144
method with 3 params: a=1 b=2 c=3
Example 2
Shows how to connect several tasks by mean of signals to create a workflow.
import {createSignal, emit, connect} from 'slot-signal'
class Task {
constructor() {
createSignal(this, 'finished')
}
run() {}
}
class LongTask extends Task {
run() {
console.log('LongTask is running...')
setTimeout( () => {
console.log('...done.')
emit(this, 'finished')
}, 1000)
}
}
class VeryLongTask extends Task {
run() {
console.log('VeryLongTask is running...')
setTimeout( () => {
console.log('...done.')
emit(this, 'finished')
}, 3000)
}
}
class TaskManager extends Task {
start() {
console.time('Elapsed time')
const longTask = new LongTask()
const veryLongTask = new VeryLongTask()
connect(longTask, 'finished', veryLongTask, 'run')
connect(veryLongTask, 'finished', () => console.log('All tasks are done!') )
connect(veryLongTask, 'finished', this, 'done')
longTask.run()
}
done() {
console.timeEnd('Elapsed time')
}
}
const manager = new TaskManager()
manager.start()
Will display
LongTask is running...
...done.
VeryLongTask is running...
...done.
All tasks are done!
Elapsed time: 4005.322998046875ms