nodejs_process_stdin_on_example
process.stdin.setEncoding('utf8')
process.stdout.setEncoding('utf8')
process.stderr.setEncoding('utf8')
EVENT = {
DEFAULT : Symbol('default'),
ALL : Symbol('all'),
}
EventTable = []
function data_listener(pattern, listener, data, once) {
let text = data.replace(/\n$/,'')
switch (pattern) {
case EVENT.DEFAULT:
var trigger = true
for (let e of EventTable.filter(e=>typeof e.pattern!='symbol')) {
let p = e.pattern
trigger = typeof p == 'string' ? p != text : !p.test(text)
if (!trigger) break
}
break
case EVENT.ALL:
var trigger = true
break
default:
var trigger = typeof pattern == 'string' ? pattern == text : pattern.test(text)
break
}
if (trigger) {
listener(data)
if (once) {
process.stdin.removeListener('data', once)
EventTable = EventTable.filter(e=>e.dataListener!=once)
}
}
}
function process_stdin_on(pattern, listener) {
let event = {
pattern : pattern,
listener : listener,
dataListener : (data) => {
data_listener(event.pattern, event.listener, data)
},
}
EventTable.push(event)
process.stdin.on('data', event.dataListener)
}
function process_stdin_once(pattern, listener) {
let event = {
pattern : pattern,
listener : listener,
dataListener : (data) => {
data_listener(event.pattern, event.listener, data, event.dataListener)
},
}
EventTable.push(event)
process.stdin.on('data', event.dataListener)
}
////////////////////////////////////////////////////////////////////////////////
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) )
output('数当てゲーム!!')
output('0 〜 100 の間の整数を当ててください')
output('答え:', '')
process_stdin_on(answer.toString(), (data) => {
output(`正解!! ${answer}`)
process.exit(0)
})
process_stdin_on('', (data) => {
error('ゲームを中止しました。')
error(`答えは ${answer} でした。`)
process.exit(1)
})
process_stdin_once('hint', (data) => {
if (answer > 50) {
output('答えは50より大きいです。','')
} else {
output('答えは50以下です。','')
}
output('hintは一回だけ!')
})
process_stdin_on(/[^0-9]+/, (data) => {
error('半角数字の正数でお願いします')
})
process_stdin_on(EVENT.DEFAULT, (data) => {
let d = data.trim()
if (d > 100 || d < 0) {
output(`答えは 0 〜 100 の間で!`)
} else if (d > answer) {
output(`${d}は大きい`)
} else if (d < answer) {
output(`${d}は小さい`)
} else {
error('===EVENT.DEFAULTが発火しました。文字列と正規表現のパターンにマッチしませんでした。=== d:' + d)
}
})
process_stdin_on(EVENT.ALL, (data) => {
output('答え:', '')
})