Skip to content

Instantly share code, notes, and snippets.

@uchcode
Created August 30, 2017 23:24
Show Gist options
  • Save uchcode/79b0e3a9b7611a6378ffb0ea57cc60e1 to your computer and use it in GitHub Desktop.
Save uchcode/79b0e3a9b7611a6378ffb0ea57cc60e1 to your computer and use it in GitHub Desktop.
nodejs eventemitter example
class StdioEmitter {
constructor(encoding='utf8') {
this.EVENT = {
DEFAULT : Symbol(),
ALL : Symbol(),
}
this.encoding = encoding
this.emitter = new (require('events').EventEmitter)()
this._event_all_listener = undefined
this._regexp_listener_dictionary = {}
this._base_listener = (data) => {
if (Object.prototype.toString.call(data).slice(8,-1).toLowerCase() != 'string') {
return
}
try {
let d = JSON.parse(data.trim())
if (!this.emitter.emit(d.eventName, d.data)) {
this.emitter.emit(this.EVENT.DEFAULT, d.data)
}
} catch(e) {
let d = data.replace(/\n$/,'')
if (!this.emitter.emit(d, data)) {
this.emitter.emit(this.EVENT.DEFAULT, data)
}
}
}
process.stdin.on('data', this._base_listener)
}
on(eventName, listener) {
switch(eventName) {
case this.EVENT.ALL:
if (this._event_all_listener) {
throw new Error(`on(): already regist. EVENT.ALL.`)
}
process.stdin.on('data', listener)
this._event_all_listener = listener
break
default:
let type = Object.prototype.toString.call(eventName).slice(8,-1).toLowerCase()
if (type == 'regexp') {
if (this._regexp_listener_dictionary[eventName]) {
throw new Error(`on(): already regist. RegExp: ${eventName}`)
}
process.stdin.on('data', listener)
this._regexp_listener_dictionary[eventName] = listener
} else {
this.emitter.on(eventName, listener)
}
break
}
}
off(eventName, listener) {
switch(eventName) {
case this.EVENT.ALL:
if (this._event_all_listener) {
process.stdin.removeListener('data', this._event_all_listener)
this._event_all_listener = undefined
}
break
default:
let type = Object.prototype.toString.call(eventName).slice(8,-1).toLowerCase()
if (type == 'regexp') {
process.stdin.removeListener('data', listener)
if (this._regexp_listener_dictionary[eventName] == listener) {
delete this._regexp_listener_dictionary[eventName]
}
} else {
this.emitter.removeListener(eventName, listener)
}
break
}
}
offAll(eventName) {
switch(eventName) {
case this.EVENT.ALL:
if (this._event_all_listener) {
process.stdin.removeListener('data', this._event_all_listener)
this._event_all_listener = undefined
}
break
default:
let type = Object.prototype.toString.call(eventName).slice(8,-1).toLowerCase()
if (type == 'regexp') {
let listener = this._regexp_listener_dictionary[eventName]
if (listener) {
process.stdin.removeListener('data', listener)
delete this._regexp_listener_dictionary[eventName]
}
} else {
this.emitter.removeAllListeners(eventName)
}
break
}
}
removeListener(eventName, listener) {
this.off(eventName, listener)
}
removeAllListeners(eventName) {
this.offAll(eventName)
}
once(eventName, listener) {
this.emitter.once(eventName, listener)
}
emit(data, argument='') {
switch(data) {
case this.EVENT.DEFAULT:
this.emitter.emit(this.EVENT.DEFAULT, argument)
break
default:
process.stdin.emit('data', data)
break
}
}
regexp(eventName, listener) {
return [eventName, (data) => {
try {
let d = data.replace(/\n$/,'')
if ( eventName.test(d) ) {
listener(data)
}
} catch(e) {
//console.log(e)
}
}]
}
set encoding(e) {
process.stdin.setEncoding(e)
process.stdout.setEncoding(e)
process.stderr.setEncoding(e)
}
get encoding() {
return process.stdin._readableState.encoding
}
}
///////////////////////////////////////////
function output(data, terminator='\n') {
process.stdout.write(data + terminator)
}
function error(data, terminator='\n') {
process.stderr.write(data + terminator)
}
answer = Math.floor( Math.random() * (100) )
rule = new StdioEmitter()
EVENT = rule.EVENT
rule.on(answer.toString(), () => {
output(`正解!! ${answer}`)
process.exit(0)
})
rule.on('', () => {
error('ゲームを中止しました。')
error(`答えは ${answer} でした。`)
process.exit(1)
})
rule.once('hint', () => {
if (answer > 50) {
output('答えは50より大きいです')
} else {
output('答えは50以下です')
}
})
rule.on(...rule.regexp( /[^0-9]+/, (data) => {
if (data.trim() == 'hint') {
output('hintは一回だけ!')
} else {
error('半角数字の正数でお願いします')
}
}))
rule.on(EVENT.DEFAULT, (data) => {
let d = data.trim()
if (d > 100 || d <= 0) {
output(`答えは 1 〜 100 の間で!`)
} else if (d > answer) {
output(`${d}は大きい`)
} else if (d < answer) {
output(`${d}は小さい`)
}
})
rule.on(EVENT.ALL, (data) => {
output('答え:', '')
})
output('数当てゲーム!!')
output('1 〜 100 の間の整数を当ててください')
rule.emit(EVENT.ALL)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment