Changeset 269

Show
Ignore:
Timestamp:
08/15/06 00:15:22 (2 years ago)
Author:
ged
Message:
  • Changed thread-per-event model to two threads: one for user-interaction and one for simulated world events.
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/docs/smoke_and_mirrors.rb

    r268 r269  
    11#!/usr/bin/ruby 
     2 
     3require 'thread' 
     4require 'readline' 
    25 
    36# 
     
    5356    }, 
    5457    { 
    55         :delay => 7, 
     58        :delay => 3, 
    5659        :output => "You continue walking through the forest towards Barrowton. You can\n" + 
    5760            "see the path to the town ahead of you.\n" 
     
    6770    # remember Barrowton 
    6871    "You have visited Barrowton only once before. You remember the folks as\n" + 
    69         "friendly and welcoming. You met Phaedrus there for the first time.  Aodh‡n\n" +  
     72        "friendly and welcoming. You met Phaedrus there for the first time.  Aodhán\n" +  
    7073        "once defeated a banshee not far from the town.", 
    7174 
     
    8285    ### Feature: Meeting someone you don't know will only show their description 
    8386    { 
    84         :delay => 3, 
     87        :delay => 2, 
    8588        :output => "A short humanoid with bluish-grey skin walks past you, away from \n" + 
    8689            "Barrowton.\n", 
    8790    }, 
    8891    { 
    89         :delay => 7, 
     92        :delay => 2, 
    9093        :output => "You have reached the entrace of Barrowton.\n", 
    9194    }, 
     
    9497    ### Feature: Combat. 
    9598    { 
    96         :delay => 11, 
     99        :delay => 2, 
    97100        :output => "Suddenly, a rabid squirrel-monkey leaps out onto the path in \n" + 
    98101            "front of you.\n", 
     
    100103     
    101104    ### Feature: complex actions as recipes 
    102     # use senu-oti style defense 
     105    # use turning defense 
    103106    { 
    104107        :delay => 1, 
     
    106109    }, 
    107110    { 
    108         :delay => 2, 
    109         :output => "You spin on your left foot in sen-paksha, and avoid the \n" + 
     111        :delay => 1, 
     112        :output => "You spin on your left foot in a crouch, and avoid the \n" + 
    110113            "monkey's attack.\n", 
    111114    }, 
    112115    { 
    113         :delay => 3, 
     116        :delay => 1, 
    114117        :output => "The monkey falls to the ground in a heap. It looks somewhat\n" + 
    115118            "dazed.\n", 
    116119    }, 
    117120    { 
    118         :delay => 4, 
     121        :delay => 1, 
    119122        :output => "It shrieks in anger, and charges your leg.\n", 
    120123    }, 
    121124    { 
    122         :delay => 5, 
     125        :delay => 1, 
    123126        :output => "You crouch in the cat pose, and deflect the monkey's bite with\n" + 
    124127            "your satchel with a loud thump. The monkey falls to the ground.\n", 
     
    133136    ### Oaths? 
    134137    ### Story elements 
     138 
     139 
     140    # quit 
    135141]  
    136142 
    137143 
    138144def debug_msg( msg ) 
    139     $deferr.puts msg if $DEBUG 
     145    $deferr.puts "DEBUG>>> " + msg if $DEBUG 
    140146end 
    141147 
     
    150156 
    151157$defout.sync = true 
    152 pending = ThreadGroup.new 
    153 done = ThreadGroup.new 
    154158 
    155 def handle_threads 
    156     pending.list.each do |thr| 
    157         debug_msg "Joining thread %p" % [ thr ] 
    158         begin 
    159             thr.join unless thr.alive? || thr == Thread.current 
    160         rescue Exception => err 
    161             $deferr.puts "*** Error: %s" % [err.message] 
    162             $deferr.puts "  " + err.stacktrace.join( "\n  " ) if $DEBUG 
    163         end 
    164         done.add( thr ) 
     159pending_events = Queue.new 
     160world_simulator = Thread.new do 
     161    puts "** World starting up **\n" 
     162    Thread.current.abort_on_exception = true 
     163    Thread.current[:run] = true 
     164 
     165    while Thread.current[:run] 
     166        debug_msg "Waiting on an event." 
     167        event = pending_events.pop 
     168     
     169        debug_msg "Got an event. Firing in %d seconds..." % event[:delay] 
     170        sleep event[:delay] 
     171        print "\n" + event[:output] + "\n>" 
    165172    end 
    166  
     173     
     174    puts "** World shutting down **\n" 
    167175end 
    168176 
    169177Output.each do |event| 
    170     handle_threads 
    171  
    172178    case event 
    173179    when String 
     
    175181        gets 
    176182    when Hash 
    177         thr = Thread.new { 
    178             Thread.current.abort_on_exception = true 
    179             sleep event[:delay]; print "\n" + event[:output] + "\n>" 
    180         } 
    181         debug_msg "Started delayed event in thread: %p" % [thr] 
    182         pending.add( thr ) 
    183         debug_msg "Pending thread group now has %d events" % [pending.list.length] 
     183        debug_msg "Queueing event '%s...' for +%ds" %  
     184            event.values_at( :output, :delay ) 
     185        pending_events.push( event ) 
    184186    end 
    185187end 
    186188 
    187 until pending.list.empty? 
    188     handle_threads 
    189     sleep 0.25 
    190 end 
    191  
    192  
    193 __END__ 
    194  
     189debug_msg "Done with main loop. Injecting final event into simulator." 
     190world_simulator[:run] = false 
     191pending_events.push({ :delay => 0, :output => "Quitting." }) 
     192debug_msg "Joining world_simulator" 
     193world_simulator.join 
     194debug_msg "Done."