Class: SSCBot::ChatLog

Inherits:
Object
  • Object
show all
Extended by:
AttrBool::Ext
Includes:
MessageParsable
Defined in:
lib/ssc.bot/chat_log.rb,
lib/ssc.bot/chat_log/message.rb,
lib/ssc.bot/chat_log/messages.rb,
lib/ssc.bot/chat_log/message_parser.rb,
lib/ssc.bot/chat_log/message_parsable.rb

Overview

Author:

  • Jonathan Bradley Whited

Since:

  • 0.1.0

Defined Under Namespace

Modules: MessageParsable Classes: ChatMessage, FreqMessage, KillMessage, Message, MessageParser, Observer, PlayerMessage, PrivateMessage, PubMessage, QFindMessage, QLogMessage, QNamelenMessage, RemoteMessage, TeamMessage

Constant Summary

Constants included from MessageParsable

MessageParsable::MAX_NAMELEN

Instance Attribute Summary collapse

Attributes included from MessageParsable

#parser

Instance Method Summary collapse

Constructor Details

#initialize(filename, file_mode: 'rt', file_opt: {}, idle_secs: 0.250, **parser_kargs) ⇒ ChatLog

Returns a new instance of ChatLog.

Since:

  • 0.1.0



39
40
41
42
43
44
45
46
47
48
49
50
51
# 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

Instance Attribute Details

#file_modeObject

Since:

  • 0.1.0



32
33
34
# File 'lib/ssc.bot/chat_log.rb', line 32

def file_mode
  @file_mode
end

#file_optObject (readonly)

Since:

  • 0.1.0



33
34
35
# File 'lib/ssc.bot/chat_log.rb', line 33

def file_opt
  @file_opt
end

#filenameObject

Since:

  • 0.1.0



34
35
36
# File 'lib/ssc.bot/chat_log.rb', line 34

def filename
  @filename
end

#idle_secsObject

Since:

  • 0.1.0



35
36
37
# File 'lib/ssc.bot/chat_log.rb', line 35

def idle_secs
  @idle_secs
end

#observersObject (readonly)

Since:

  • 0.1.0



36
37
38
# File 'lib/ssc.bot/chat_log.rb', line 36

def observers
  @observers
end

#threadObject (readonly)

Since:

  • 0.1.0



37
38
39
# File 'lib/ssc.bot/chat_log.rb', line 37

def thread
  @thread
end

Instance Method Details

#add_observer(observer = nil, *funcs, type: :any, &block) ⇒ Object

Since:

  • 0.1.0



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 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) ⇒ Object

Since:

  • 0.1.0



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# 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) ⇒ Object

Since:

  • 0.1.0



91
92
93
94
95
96
97
98
99
100
101
# 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_contentObject

Since:

  • 0.1.0



103
104
105
# File 'lib/ssc.bot/chat_log.rb', line 103

def clear_content
  SSCFile.clear(@filename)
end

#count_observers(type: nil) ⇒ Object

Since:

  • 0.1.0



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# 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) ⇒ Object

Since:

  • 0.1.0



127
128
129
# 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) ⇒ Object

Since:

  • 0.1.0



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# 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) ⇒ Object

Since:

  • 0.1.0



157
158
159
160
161
162
163
164
165
166
167
168
# 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) ⇒ Object

Since:

  • 0.1.0



170
171
172
173
174
175
176
177
178
179
180
181
# 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) ⇒ Object

Since:

  • 0.1.0



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# 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_touchObject

Since:

  • 0.1.0



213
214
215
# File 'lib/ssc.bot/chat_log.rb', line 213

def soft_touch
  SSCFile.soft_touch(@filename)
end

#stop(wait_secs = 5) ⇒ Object

Since:

  • 0.1.0



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# 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