class SSCBot::ChatLog

@author Jonathan Bradley Whited @since 0.1.0

Attributes

file_mode[RW]
file_opt[R]
filename[RW]
idle_secs[RW]
observers[R]
thread[R]

Public Class Methods

new(filename,file_mode: 'rt',file_opt: {},idle_secs: 0.250,**parser_kargs) click to toggle source
Calls superclass method
# File lib/ssc.bot/chat_log.rb, line 39
def initialize(filename,file_mode: 'rt',file_opt: {},idle_secs: 0.250,**parser_kargs)
  super()

  @alive = false
  @file_mode = file_mode
  @file_opt = file_opt
  @filename = filename
  @idle_secs = idle_secs
  @observers = {}
  @parser = MessageParser.new(**parser_kargs)
  @semaphore = Mutex.new
  @thread = nil
end

Public Instance Methods

add_observer(observer=nil,*funcs,type: :any,&block) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 53
def add_observer(observer=nil,*funcs,type: :any,&block)
  if observer.nil? && block.nil?
    raise ArgumentError,'no observer'
  end

  check_type(type)

  type_observers = fetch_observers(type: type)

  if !observer.nil?
    funcs << :call if funcs.empty?

    type_observers << Observer.new(observer,*funcs)
  end

  if !block.nil?
    type_observers << Observer.new(block,:call)
  end
end
add_observers(*observers,type: :any,func: :call,&block) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 73
def add_observers(*observers,type: :any,func: :call,&block)
  if observers.empty? && block.nil?
    raise ArgumentError,'no observer'
  end

  check_type(type)

  type_observers = fetch_observers(type: type)

  observers.each do |observer|
    type_observers << Observer.new(observer,func)
  end

  if !block.nil?
    type_observers << Observer.new(block,:call)
  end
end
check_type(type,nil_ok: false) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 91
def check_type(type,nil_ok: false)
  if type.nil?
    if !nil_ok
      raise ArgumentError,"invalid type{#{type.inspect}}"
    end
  else
    if type != :any && !Message.valid_type?(type)
      raise ArgumentError,"invalid type{#{type.inspect}}"
    end
  end
end
clear_content() click to toggle source
# File lib/ssc.bot/chat_log.rb, line 103
def clear_content
  SSCFile.clear(@filename)
end
count_observers(type: nil) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 107
def count_observers(type: nil)
  check_type(type,nil_ok: true)

  count = 0

  if type.nil?
    @observers.each_value do |type_observers|
      count += type_observers.length
    end
  else
    type_observers = @observers[type]

    if !type_observers.nil?
      count += type_observers.length
    end
  end

  return count
end
delete_observer(observer,type: nil) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 127
def delete_observer(observer,type: nil)
  delete_observers(observer,type: type)
end
delete_observers(*observers,type: nil) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 131
def delete_observers(*observers,type: nil)
  check_type(type,nil_ok: true)

  if observers.empty?
    if type.nil?
      @observers.clear
    else
      @observers[type]&.clear
    end
  else
    observers = observers.to_set

    if type.nil?
      @observers.each_value do |type_observers|
        type_observers.delete_if do |observer|
          observers.include?(observer.object)
        end
      end
    else
      @observers[type]&.delete_if do |observer|
        observers.include?(observer.object)
      end
    end
  end
end
fetch_observers(type: :any) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 157
def fetch_observers(type: :any)
  check_type(type)

  type_observers = @observers[type]

  if type_observers.nil?
    type_observers = []
    @observers[type] = type_observers
  end

  return type_observers
end
notify_observers(message) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 170
def notify_observers(message)
  any_observers = @observers[:any]
  type_observers = @observers[message.type]

  any_observers&.each do |observer|
    observer.notify(self,message)
  end

  type_observers&.each do |observer|
    observer.notify(self,message)
  end
end
run(seek_to_end: true) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 183
def run(seek_to_end: true)
  @semaphore.synchronize do
    return if @alive # Already running
  end

  stop # Justin Case

  @semaphore.synchronize do
    @alive = true

    soft_touch # Create the file if it doesn't exist

    @thread = Thread.new do
      SSCFile.open(@filename,@file_mode,**@file_opt) do |fin|
        fin.seek_to_end if seek_to_end

        while @alive
          while !(line = fin.read_uline).nil?
            message = @parser.parse(line)

            notify_observers(message)
          end

          sleep(@idle_secs)
        end
      end
    end
  end
end
soft_touch() click to toggle source
# File lib/ssc.bot/chat_log.rb, line 213
def soft_touch
  SSCFile.soft_touch(@filename)
end
stop(wait_secs=5) click to toggle source
# File lib/ssc.bot/chat_log.rb, line 217
def stop(wait_secs=5)
  @semaphore.synchronize do
    @alive = false

    if !@thread.nil?
      if @thread.alive?
        # First, try to kill it gracefully (waiting X secs).
        @thread.join(@idle_secs + wait_secs)

        # Die!
        @thread.kill if @thread.alive?
      end

      @thread = nil
    end
  end
end