0.0.4 • Published 6 years ago

slot-signal v0.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

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

  1. connect(emitter, signalName, receiver, slotName)
  2. connect(emitter, signalName, receiver.method)
  3. connect(emitter, signalName, function)
  4. 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
0.0.4

6 years ago

0.0.3

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago