TeensyMud - 'A ruby mud server.'

Browse repository
back

engine.rb

#
# file:: engine.rb
# author:: Jon A. Lambert
# version:: 2.10.0
# date:: 06/25/2006
#
# This source code copyright (C) 2005, 2006 by Jon A. Lambert
# All rights reserved.
#
# Released under the terms of the TeensyMUD Public License
# See LICENSE file for additional information.
#
$:.unshift "lib" if !$:.include? "lib"
$:.unshift "vendor" if !$:.include? "vendor"

require 'singleton'

require 'utility/configuration'
require 'utility/log'
require 'network/reactor'
require 'core/world'
require 'engine/eventmanager'
require 'core/room'
require 'core/character'
require 'core/gameobject'
require 'core/account'
require 'core/exit'
require 'core/script'

# The Engine class sets up the server, polls it regularly and observes
# acceptor for incoming connections.
class Engine
include Singleton
configuration
logger 'DEBUG'

attr_accessor :shutdown
attr_reader :world, :db, :eventmgr

# Create the an engine.
# [+return+] A handle to the engine.
def initialize
# Display options
log.debug "Configuration: #{options.inspect}"
@shutdown = false
if options['trace']
set_trace_func proc { |event, file, line, id, binding, classname|
if file !~ /\/usr\/lib\/ruby/
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
end
}
end
end

# main loop to run engine.
# note:: @shutdown never set by anyone yet
def run
case options['dbtype']
when :yaml
require 'storage/yamlstore'
@db = YamlStore.new(options['dbfile'])
when :xml
require 'storage/xmlstore'
@db = XmlStore.new(options['dbfile'])
when :gdbm
require 'storage/gdbmstore'
@db = GdbmStore.new(options['dbfile'])
when :sdbm
require 'storage/sdbmstore'
@db = SdbmStore.new(options['dbfile'])
when :dbm
require 'storage/dbmstore'
@db = DbmStore.new(options['dbfile'])
when :sqlite
require 'storage/sqlitestore'
@db = SqliteStore.new(options['dbfile'])
when :sqlite3
require 'storage/sqlite3store'
@db = Sqlite3Store.new(options['dbfile'])
else
log.fatal "Invalid 'dbtype' in Configuration"
raise RunTimeError
end

# Get the world object
@world = @db.get(0)
# log.debug @world.inspect
@db.makenoswap(0)
@world.startup

@eventmgr = EventManager.new
log.info "Booting server on port #{options['server_port'] || 4000}"
@server = Reactor.new(options['server_port'] || 4000,
options['server_type'], options['server_io'],
options['server_negotiation'], options['server_filters'],
address=nil)

raise "Unable to start server" unless @server.start(self)
log.info "TMUD is ready"

Signal.trap("INT", method(:handle_signal))
Signal.trap("TERM", method(:handle_signal))
Signal.trap("KILL", method(:handle_signal))
until @shutdown
@server.poll(0.3)
@eventmgr.process_events
end # until
graceful_shutdown
rescue
log.fatal "Engine failed in run"
log.fatal $!
end

# Update is called by an acceptor passing us a new session. We create
# an incoming object and set it and the connection to watch each other.
def update(newconn)
inc = Account.new(newconn)
# Observe each other
newconn.subscribe(inc)
inc.subscribe(newconn)
end

# Setup traps - invoke one of these signals to shut down the mud
def handle_signal(sig)
log.warn "Signal caught request to shutdown."
graceful_shutdown
end

def graceful_shutdown
@world.shutdown
@server.stop
log.info "Saving world..."
@db.save
@db.close
exit
end
end