Permalink
Browse files

Quizmaster threading and static member variable to ask questions

  * Turns out Robut spawns a new instance on each request so to have
    question continuity I needed to use a @@member_var
  • Loading branch information...
1 parent 8c1a9c5 commit 33f6498a4f2c5889c677991ddf37675e38d0fa15 @burtlo committed Oct 23, 2011
Showing with 59 additions and 31 deletions.
  1. +59 −31 lib/quiz.rb
View
@@ -4,15 +4,9 @@
class Robut::Plugin::Quiz
include Robut::Plugin
- QUESTION_REGEX = /^ask ?(choice|polar|scale)? (?:question )?.+(?:(?:for )?(\d+) minutes?)$/
- ANSWER_REGEX = /^answer .+$/
-
def usage
[
- "#{at_nick} ask choice question 'What do you want for lunch?', 'pizza', 'sandwich', 'salad' for 1 minute",
"#{at_nick} ask polar 'Should I continue the presentation?' for 3 minutes",
- "#{at_nick} ask scale 'how much did you like the presentation?', '1..5' for 2 minutes",
- "#{at_nick} ask 'Should I continue the presentation?', 'y|yes', 'n|no' for 1 minutes"
]
end
@@ -23,40 +17,55 @@ def handle(time, sender_nick, message)
if sent_to_me? message and is_a_valid_question? request
- enqueue_the_question time, sender_nick, request
+ enqueue_the_question sender_nick, request
+ reply "@#{sender_nick}, I have enqueued your question"
+ quizmaster
end
if sent_to_me? message and currently_asking_a_question? and is_a_valid_response? request
-
- process_response_for_active_question time, sender_nick, request
-
+ process_response_for_active_question sender_nick, request
end
+ rescue => exception
+ reply "Problem: #{exception}"
end
+ QUESTION_REGEX = /^ask ?(choice|polar|scale)? (?:question )?.+(?:(?:for )?(\d+) minutes?)$/
+
def is_a_valid_question? message
QUESTION_REGEX =~ message
end
+ ANSWER_REGEX = /^answer .+$/
+
def is_a_valid_response? message
ANSWER_REGEX =~ message
end
- def enqueue_the_question(time,sender,question)
- # enqueue the question with a unique identifier
- (store["quiz::question_queue"] ||= []) << [time,sender,question]
- # start a worker thread unless one has already been started
+ def enqueue_the_question(sender,question)
+ (store["quiz::question::queue"] ||= []) << [sender,question]
+ end
+
+ def quizmaster
+ @@quizmaster ||= Thread.new { pop_the_question until there_are_no_more_questions_to_pop }
+ end
+
+ def pop_the_question
+ if popped_question = (store["quiz::question::queue"] ||= []).pop
+ process_the_question *popped_question
+ end
end
- # if there are no active questions then ask the question
- # TODO: create the question worker
+ def there_are_no_more_questions_to_pop
+ (store["quiz::question::queue"] ||= []).empty?
+ end
def currently_asking_a_question?
- @current_question
+ defined? @@current_question and @@current_question
end
- def process_the_question(time,sender,request)
+ def process_the_question(sender,request)
request =~ QUESTION_REGEX
type = Regexp.last_match(1) || 'polar'
@@ -65,6 +74,12 @@ def process_the_question(time,sender,request)
set_current_question create_the_question_based_on_type(type,sender,request), question_length
end
+ #
+ # @param [String] question_type the name of the question type which will be
+ # converted from a String to the Class name within the current namespace.
+ # @param [String] sender the sender of the question
+ # @param [String] request the entire message that initiated the question
+ #
def create_the_question_based_on_type(question_type,sender,request)
self.class.const_get(question_type.capitalize).new sender, request
end
@@ -74,29 +89,37 @@ def set_current_question(question,length_of_time)
start_accepting_responses_for_this_question question
reply question.ask
-
+
sleep length_of_time.to_i * 60
stop_accepting_responses_for_this_question question
+ reply "The results are in for '#{question}':"
reply question.results
end
def start_accepting_responses_for_this_question(question)
- @current_question = question
+ @@current_question = question
end
def stop_accepting_responses_for_this_question(question)
- @current_question = nil
+ @@current_question = nil
end
- def process_response_for_active_question(time,sender_nick, request)
- @current_question.handle_response time, sender_nick, request
+ def process_response_for_active_question(sender_nick, request)
+ if @@current_question.handle_response sender_nick, request
+ reply "@#{sender_nick} I have received a response"
+ else
+ reply "@#{sender_nick} I did not understand that answer"
+ end
end
end
+
+
+
module Robut::Plugin::Quiz::Question
# @see ask%20%3F(choice%7Cpolar%7Cscale)%3F%20(%3F%3Aquestion%20)%3F'(%5B%5E'%5D%2B)'%5B%5Cs%2C%5D*((%3F%3A'%5B%5E'%5D%2B'%5B%5Cs%2C%5D*)*)%2B(%3F%3A(%3F%3Afor%20)%3F(%5Cd%2B)%20minutes%3F)%3F
@@ -105,10 +128,10 @@ module Robut::Plugin::Quiz::Question
# 2nd: question
# 3rd: choices
#
- QUESTION_REGEX = /^ask ?(choice|polar|scale)? (?:question )?'([^']+)'[\s,]*((?:'[^']+'[\s,]*)*)*(?:(?:for )?(\d+) minutes?)?$/
+ QUESTION_REGEX = /^ask ?(choice|polar|scale)? (?:question )?['"]([^'"]+)['"][\s,]*((?:['"][^'"]+['"][\s,]*)*)*(?:(?:for )?(\d+) minutes?)?$/
# This regex will find all the questions and parameters specified with the question
- GROUP_REGEX = /'([^']+)'/
+ GROUP_REGEX = /['"]([^'"]+)['"]/
def initialize(sender,request)
@sender = sender
@@ -125,6 +148,14 @@ def process_question(request)
end
+ def to_s
+ @question
+ end
+
+ def ask
+ "@all Question '#{@question}'"
+ end
+
end
class Robut::Plugin::Quiz::Polar
@@ -133,17 +164,14 @@ class Robut::Plugin::Quiz::Polar
YES_ANSWER = /y|yes/i
NO_ANSWER = /n|no/i
-
- def ask
- "@#{@sender} asks '#{@question}' (yes/no)"
- end
-
- def handle_response(time,sender_nick,response)
+ def handle_response(sender_nick,response)
if response =~ YES_ANSWER
store_positive_response_for sender_nick
elsif response =~ NO_ANSWER
store_negative_response_for sender_nick
+ else
+ nil
end
end

0 comments on commit 33f6498

Please sign in to comment.