Skip to content

Instantly share code, notes, and snippets.

@uchcode
Last active August 30, 2017 01:47
Show Gist options
  • Save uchcode/ead4920740e4571aa556991268829686 to your computer and use it in GitHub Desktop.
Save uchcode/ead4920740e4571aa556991268829686 to your computer and use it in GitHub Desktop.
node.js stdio example
const STDIN = {
DEFAULT : Symbol(),
ALL : Symbol(),
BEFORE_ALL : Symbol(),
AFTER_ALL : Symbol(),
}
class ProcessStdio {
constructor(encoding='utf8') {
this.encoding = encoding
this.events = []
this.listeners = {}
}
set encoding(e) {
process.stdin.setEncoding(e)
process.stdout.setEncoding(e)
process.stderr.setEncoding(e)
}
get encoding() {
return process.stdin._readableState.encoding
}
//TODO ターミネーターの送り方を調べる
input(data, terminator='\n') {
process.stdin.write(data + terminator)
}
output(data, terminator='\n') {
process.stdout.write(data + terminator)
}
error(data, terminator='\n') {
process.stderr.write(data + terminator)
}
exit(code=0) {
process.exit(code)
}
on(event, listener, once=false) {
this.events.push(event)
this.listeners[event] = {listener:listener,once:once}
switch(Object.prototype.toString.call(event).slice(8,-1).toLowerCase()) {
case 'string':
process.stdin.on('data', (data) => {
let d = data.replace(/\n$/,'')
if (this.listeners[d]) {
this.listeners[d].listener(d)
if (this.listeners[d].once) {
delete this.events[this.events.indexOf(d)]
delete this.listeners[d]
}
}
})
break
case 'symbol':
switch(event) {
case STDIN.DEFAULT:
process.stdin.on('data', (data) => {
let d = data.replace(/\n$/,'')
if (this.events.indexOf(d)==-1) {
this.listeners[event].listener(d)
if (this.listeners[event].once) {
delete this.events[this.events.indexOf(event)]
delete this.listeners[event]
}
}
})
break
case STDIN.ALL:
process.stdin.on('data', (data) => {
this.listeners[event].listener(data.replace(/\n$/,''))
if (this.listeners[event].once) {
delete this.events[this.events.indexOf(event)]
delete this.listeners[event]
}
})
break
}
break
case 'regexp':
process.stdin.on('data', (data) => {
let d = data.replace(/\n$/,'')
if (event.test(d)) {
this.listeners[event].listener(d)
if (this.listeners[event].once) {
delete this.events[this.events.indexOf(event)]
delete this.listeners[event]
}
}
})
break
default:
console.log('type is default')
break
}
}
once(event, listener) {
this.on(event, listener, true)
}
emit(event, argument) { //ここも引数を熟考
if (!argument) argument = event
this.listeners[event].listener(argument)
}
onError(listener) {
}
}
///////////////////////////////////////////
ans = Math.floor( Math.random() * (100) )
app = new ProcessStdio()
app.output('数当てゲーム!!')
app.output('1 〜 100 の間の整数を当ててください')
app.on(ans.toString(), () => {
app.output(`正解!! ${ans}`)
app.exit(0)
})
app.on('', () => {
app.error('ゲームを中止しました。')
app.error(`答えは ${ans} でした。`)
app.exit(1)
})
app.once('hint', () => {
if (ans > 50) {
app.output('答えは50より大きいです')
} else {
app.output('答えは50以下です')
}
})
app.on(/[^0-9]+/, (data) => {
if (data == 'hint') {
app.output('hintは一回だけ!')
} else {
app.error('半角数字の正数でお願いします')
}
})
app.on(STDIN.DEFAULT, (data) => {
let d = data.replace(/\n$/, '')
if (d > 100 || d <= 0) {
app.output(`答えは 1 〜 100 の間で!`)
} else if (d > ans) {
app.output(`${d}は大きい`)
} else if (d < ans) {
app.output(`${d}は小さい`)
}
})
app.on(STDIN.ALL, () => {
app.output('答え:', '')
})
app.emit(STDIN.ALL)
// console.log(app)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment