dramatis 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. data/History.txt +7 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +119 -0
  4. data/README.txt +57 -0
  5. data/Rakefile +4 -0
  6. data/config/hoe.rb +70 -0
  7. data/config/requirements.rb +17 -0
  8. data/examples/README.txt +20 -0
  9. data/examples/auction.rb +90 -0
  10. data/examples/bank/bank.rb +7 -0
  11. data/examples/bank/bank_test.rb +7 -0
  12. data/examples/exception.rb +40 -0
  13. data/examples/fib/conservative.rb +50 -0
  14. data/examples/fib/future.rb +5 -0
  15. data/examples/fib/original.rb +33 -0
  16. data/examples/fib/threads.rb +51 -0
  17. data/examples/im/distributed/chat/client.rb +49 -0
  18. data/examples/im/distributed/chat/screen/fox.rb +92 -0
  19. data/examples/im/distributed/chat/screen.rb +11 -0
  20. data/examples/im/distributed/chat/server.rb +72 -0
  21. data/examples/im/distributed/chat.rb +5 -0
  22. data/examples/im/distributed/client.rb +9 -0
  23. data/examples/im/distributed/run.rb +18 -0
  24. data/examples/im/distributed/server.rb +11 -0
  25. data/examples/im/single/chat/client.rb +50 -0
  26. data/examples/im/single/chat/screen/fox.rb +96 -0
  27. data/examples/im/single/chat/screen/wxs.rb +63 -0
  28. data/examples/im/single/chat/screen.rb +11 -0
  29. data/examples/im/single/chat/server.rb +72 -0
  30. data/examples/im/single/chat.rb +5 -0
  31. data/examples/im/single/fox.rb +18 -0
  32. data/examples/im/single/wxchat.rb +19 -0
  33. data/examples/pingpong/actor.rb +33 -0
  34. data/examples/pingpong/actor_rec.rb +34 -0
  35. data/examples/pingpong/pingpong.txt +315 -0
  36. data/examples/pingpong/scala.rb +41 -0
  37. data/examples/pingpong/serial.rb +26 -0
  38. data/examples/pretty.txt +108 -0
  39. data/examples/telephone/.irbrc +2 -0
  40. data/examples/telephone/3esl.txt +21877 -0
  41. data/examples/telephone/fifth/kid.rb +36 -0
  42. data/examples/telephone/fifth/run.rb +26 -0
  43. data/examples/telephone/first/kid.rb +31 -0
  44. data/examples/telephone/first/run.rb +20 -0
  45. data/examples/telephone/fourth/kid.rb +31 -0
  46. data/examples/telephone/fourth/run.rb +26 -0
  47. data/examples/telephone/mangler.rb +53 -0
  48. data/examples/telephone/second/kid.rb +26 -0
  49. data/examples/telephone/second/run.rb +20 -0
  50. data/examples/telephone/seventh/kid.rb +40 -0
  51. data/examples/telephone/seventh/run.rb +35 -0
  52. data/examples/telephone/seventh/test.rb +28 -0
  53. data/examples/telephone/seventh/test2.rb +10 -0
  54. data/examples/telephone/sixth/kid.rb +39 -0
  55. data/examples/telephone/sixth/run.rb +26 -0
  56. data/examples/telephone/third/kid.rb +31 -0
  57. data/examples/telephone/third/run.rb +21 -0
  58. data/lib/dramatis/actor/interface.rb +118 -0
  59. data/lib/dramatis/actor/name/interface.rb +128 -0
  60. data/lib/dramatis/actor/name.rb +44 -0
  61. data/lib/dramatis/actor.rb +96 -0
  62. data/lib/dramatis/deadlock.rb +123 -0
  63. data/lib/dramatis/error/uncaught.rb +19 -0
  64. data/lib/dramatis/error.rb +125 -0
  65. data/lib/dramatis/future/interface.rb +45 -0
  66. data/lib/dramatis/future.rb +32 -0
  67. data/lib/dramatis/runtime/actor/main.rb +3 -0
  68. data/lib/dramatis/runtime/actor.rb +294 -0
  69. data/lib/dramatis/runtime/gate.rb +244 -0
  70. data/lib/dramatis/runtime/scheduler.rb +374 -0
  71. data/lib/dramatis/runtime/task.rb +390 -0
  72. data/lib/dramatis/runtime/thread_pool.rb +149 -0
  73. data/lib/dramatis/runtime/timer.rb +5 -0
  74. data/lib/dramatis/runtime.rb +129 -0
  75. data/lib/dramatis/shoes/runtime.rb +7 -0
  76. data/lib/dramatis/shoes.rb +14 -0
  77. data/lib/dramatis/version.rb +8 -0
  78. data/lib/dramatis.rb +73 -0
  79. data/log/debug.log +0 -0
  80. data/script/destroy +14 -0
  81. data/script/generate +14 -0
  82. data/script/txt2html +74 -0
  83. data/setup.rb +1585 -0
  84. data/spec/dramatis/actor/become_spec.rb +17 -0
  85. data/spec/dramatis/actor/future_spec.rb +189 -0
  86. data/spec/dramatis/actor/name_spec.rb +141 -0
  87. data/spec/dramatis/actor/task_spec.rb +75 -0
  88. data/spec/dramatis/actor_spec.rb +492 -0
  89. data/spec/dramatis/dramatis_spec.rb +23 -0
  90. data/spec/dramatis/exc_spec.rb +78 -0
  91. data/spec/dramatis/runtime/gate_spec.rb +57 -0
  92. data/spec/dramatis/runtime/thread_pool.rb +30 -0
  93. data/spec/dramatis/shoes_spec.rb +11 -0
  94. data/spec/dramatis/simple_spec.rb +32 -0
  95. data/spec/exp_spec.rb +21 -0
  96. data/spec/simple2_spec.rb +36 -0
  97. data/spec/simple_spec.rb +30 -0
  98. data/spec/spec.opts +0 -0
  99. data/spec/spec_helper.rb +26 -0
  100. data/spec/thread_spec.rb +13 -0
  101. data/tasks/deployment.rake +34 -0
  102. data/tasks/environment.rake +7 -0
  103. data/tasks/rspec.rake +21 -0
  104. data/tasks/website.rake +17 -0
  105. data/test/jruby_lm.rb +13 -0
  106. data/test/test.rb +19 -0
  107. data/test/test10.rb +43 -0
  108. data/test/test11.rb +45 -0
  109. data/test/test12.rb +60 -0
  110. data/test/test13.rb +71 -0
  111. data/test/test2.rb +12 -0
  112. data/test/test3.rb +10 -0
  113. data/test/test4.rb +29 -0
  114. data/test/test5.rb +8 -0
  115. data/test/test6.rb +32 -0
  116. data/test/test7.rb +48 -0
  117. data/test/test8.rb +133 -0
  118. data/test/test9.rb +105 -0
  119. data/test/test_exc.rb +22 -0
  120. metadata +180 -0
@@ -0,0 +1,92 @@
1
+ module Chat; end
2
+ module Chat::Screen; end
3
+
4
+ require 'dramatis/actor'
5
+ require 'rubygems'
6
+ require 'fox16'
7
+
8
+ module Chat::Screen::Fox
9
+
10
+ class Server
11
+
12
+ include Dramatis::Actor
13
+
14
+ attr_reader :fox
15
+
16
+ def initialize
17
+ actor.always :fox, true
18
+ @fox = Fox::FXApp.new
19
+ @fox.create
20
+ ( interface( Runtime.new ).continue nil ).run @fox
21
+ end
22
+
23
+ def new *args
24
+ Window.new( actor.name, *args )
25
+ end
26
+
27
+ class Runtime
28
+ include Dramatis::Actor
29
+ def run fox
30
+ fox.run
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ class Window
37
+
38
+ include Dramatis::Actor
39
+
40
+ def initialize server, client, options
41
+
42
+ @server = server
43
+ @client = client
44
+ @options = options
45
+
46
+ @window = Fox::FXMainWindow.new server.fox, @options[:title]
47
+ @window.connect Fox::SEL_CLOSE do; close end
48
+
49
+ @frame = Fox::FXVerticalFrame.new @window
50
+
51
+ @text = Fox::FXText.new @frame
52
+ @text.editable = false
53
+ @text.visibleColumns = 80
54
+ @text.visibleRows = 20
55
+
56
+ @input = Fox::FXTextField.new @frame, 80
57
+ @input.text = @options[:prompt]
58
+
59
+ @input.connect Fox::SEL_COMMAND do |sender,selector,data|
60
+ # NB: this is a call back from Fox
61
+ # That means this block does not hold the actor lock
62
+ # It is (probably?) an unmanged thread
63
+ # It's not clear how reliable this is or how it is
64
+ # combining Ruby and Fox event loops
65
+ begin
66
+ # raise "hell"
67
+ rescue Exception => e
68
+ pp e.backtrace
69
+ end
70
+ @input.text = @options[:prompt]
71
+ if data.index( @options[:prompt] ) == 0
72
+ data = data[ @options[:prompt].length..-1 ]
73
+ end
74
+ interface( @client ).continue( nil ) >> data
75
+ end
76
+
77
+ @window.create
78
+ @window.show
79
+
80
+ end
81
+
82
+ def << string
83
+ @text.appendText string
84
+ end
85
+
86
+ def close
87
+ @client.close
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,11 @@
1
+ module Chat; end
2
+
3
+ require 'chat/screen/fox'
4
+
5
+ module Chat::Screen
6
+
7
+ def self.new *args
8
+ Chat::Screen::Fox::Server.new( *args )
9
+ end
10
+
11
+ end
@@ -0,0 +1,72 @@
1
+ module Chat; end
2
+
3
+ require 'dramatis/actor'
4
+
5
+ class Chat::Server
6
+
7
+ include Dramatis::Actor
8
+
9
+ def initialize password
10
+ @password = password
11
+ @groups = {}
12
+ end
13
+
14
+ def connect password
15
+ if password == @password
16
+ Connection.new actor.name
17
+ else
18
+ raise "bad password"
19
+ end
20
+ end
21
+
22
+ def login group, user, client
23
+ if !actor = @groups[group]
24
+ actor = @groups[group] = Group.new( group, user, client )
25
+ else
26
+ actor.login user, client
27
+ end
28
+ actor
29
+ end
30
+
31
+ class Connection
32
+ include Dramatis::Actor
33
+ def initialize server
34
+ @server = server
35
+ end
36
+
37
+ def login group, user, client
38
+ @server.login group, user, client
39
+ end
40
+ end
41
+
42
+ class Group
43
+ include Dramatis::Actor
44
+
45
+ def initialize name, user, client
46
+ @name = name
47
+ @clients = { client => user }
48
+ @cast = interface( actor.name ).continue nil
49
+
50
+ @cast << { :user => user, :client => client, :string => "I'm starting the group" }
51
+ end
52
+
53
+ def login user, client
54
+ @clients[client] = user
55
+ @cast << { :user => user, :client => client, :string => "I'm joining the group" }
56
+ end
57
+
58
+ def logout client
59
+ user = @clients[client]
60
+ @clients.delete client
61
+ @cast << { :user => user, :client => client, :string => "I'm leaving the group" }
62
+ end
63
+
64
+ def << opts
65
+ @clients.each_key do |client|
66
+ ( interface( client ).continue nil ) << opts
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,5 @@
1
+ module Chat; end
2
+
3
+ require 'chat/screen'
4
+ require 'chat/server'
5
+ require 'chat/client'
@@ -0,0 +1,9 @@
1
+ #!/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "..", "lib" )
4
+
5
+ require 'chat'
6
+
7
+ screen = Chat::Screen.new
8
+
9
+ Chat::Client.new screen, *ARGV
@@ -0,0 +1,18 @@
1
+ #!/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "lib" )
4
+
5
+ require 'chat'
6
+
7
+ password = "xyzzy"
8
+ group = "general"
9
+
10
+ screen = Chat::Screen.new
11
+
12
+ server = Chat::Server.new password
13
+
14
+ joe = Chat::Client.new screen, server, password, group, "joe"
15
+ jane = Chat::Client.new screen, server, password, group, "jane"
16
+ jim = Chat::Client.new screen, server, password, group, "jim"
17
+ sue = Chat::Client.new screen, server, password, group, "sue"
18
+
@@ -0,0 +1,11 @@
1
+ #!/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "..", "lib" )
4
+
5
+ require 'dramatis/actor'
6
+ require 'chat'
7
+
8
+ server = Chat::Server.new ARGV
9
+
10
+ puts interface( server ).url
11
+
@@ -0,0 +1,50 @@
1
+ module Chat; end
2
+
3
+ require 'dramatis/actor'
4
+
5
+ class Chat::Client
6
+
7
+ include Dramatis::Actor
8
+
9
+ def initialize screen, server, password, group, user
10
+
11
+ @user = user
12
+
13
+ @window = screen.new actor.name, :title => user, :prompt => "#{@user} > "
14
+
15
+ @window << "connecting to server ... "
16
+
17
+ begin
18
+ @server = server.connect password
19
+ rescue Exception => e
20
+ @window << "\nfailed to connect to server: #{e}\n"
21
+ return
22
+ end
23
+
24
+ @window << "connected to server #{@server}\n"
25
+
26
+ @window << "logging in ... "
27
+
28
+ begin
29
+ @group = @server.login group, user, actor.name
30
+ @window << "done\n"
31
+ rescue Exception => e
32
+ @window << "\nlogin failed: #{e}\n"
33
+ end
34
+
35
+ end
36
+
37
+ def << opts
38
+ @window << "#{opts[:user]}@#{opts[:client]} #{opts[:string]}\n"
39
+ end
40
+
41
+ def >> string
42
+ @group << { :user => @user, :client => self, :string => string }
43
+ end
44
+
45
+ def close
46
+ @group.logout actor.name
47
+ 0
48
+ end
49
+
50
+ end
@@ -0,0 +1,96 @@
1
+ module Chat; end
2
+ module Chat::Screen; end
3
+
4
+ require 'dramatis/actor'
5
+ require 'rubygems'
6
+ require 'fox16'
7
+
8
+ module Chat::Screen::Fox
9
+
10
+ def self.new *args
11
+ Server.new( *args )
12
+ end
13
+
14
+ class Server
15
+
16
+ include Dramatis::Actor
17
+
18
+ attr_reader :fox
19
+
20
+ def initialize
21
+ actor.always :fox, true
22
+ @fox = Fox::FXApp.new
23
+ @fox.create
24
+ ( interface( Runtime.new ).continue nil ).run @fox
25
+ end
26
+
27
+ def new *args
28
+ Window.new( actor.name, *args )
29
+ end
30
+
31
+ class Runtime
32
+ include Dramatis::Actor
33
+ def run fox
34
+ fox.run
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ class Window
41
+
42
+ include Dramatis::Actor
43
+
44
+ def initialize server, client, options
45
+
46
+ @server = server
47
+ @client = client
48
+ @options = options
49
+
50
+ @window = Fox::FXMainWindow.new server.fox, @options[:title]
51
+ @window.connect Fox::SEL_CLOSE do; close end
52
+
53
+ @frame = Fox::FXVerticalFrame.new @window
54
+
55
+ @text = Fox::FXText.new @frame
56
+ @text.editable = false
57
+ @text.visibleColumns = 80
58
+ @text.visibleRows = 20
59
+
60
+ @input = Fox::FXTextField.new @frame, 80
61
+ @input.text = @options[:prompt]
62
+
63
+ @input.connect Fox::SEL_COMMAND do |sender,selector,data|
64
+ # NB: this is a call back from Fox
65
+ # That means this block does not hold the actor lock
66
+ # It is (probably?) an unmanged thread
67
+ # It's not clear how reliable this is or how it is
68
+ # combining Ruby and Fox event loops
69
+ begin
70
+ # raise "hell"
71
+ rescue Exception => e
72
+ pp e.backtrace
73
+ end
74
+ @input.text = @options[:prompt]
75
+ if data.index( @options[:prompt] ) == 0
76
+ data = data[ @options[:prompt].length..-1 ]
77
+ end
78
+ interface( @client ).continue( nil ) >> data
79
+ end
80
+
81
+ @window.create
82
+ @window.show
83
+
84
+ end
85
+
86
+ def << string
87
+ @text.appendText string
88
+ end
89
+
90
+ def close
91
+ @client.close
92
+ end
93
+
94
+ end
95
+
96
+ end
@@ -0,0 +1,63 @@
1
+ module Chat; end
2
+ module Chat::Screen; end
3
+
4
+ require 'dramatis/actor'
5
+ require 'rubygems'
6
+ require 'wx'
7
+
8
+ module Chat::Screen::WX
9
+
10
+ def self.new *args
11
+ Server.new( *args )
12
+ end
13
+
14
+ class Server
15
+ include Dramatis::Actor
16
+ attr_reader :wx
17
+ def initialize
18
+ actor.always :wx, true
19
+ @wx = App.new
20
+ release( @wx ).run
21
+ end
22
+
23
+ def new *args
24
+ @wx ||= App.new
25
+ Window.new( actor.name, *args )
26
+ end
27
+
28
+ class App < Wx::App
29
+ include Dramatis::Actor
30
+ def run
31
+ main_loop
32
+ end
33
+ def on_init
34
+ t = Wx::Timer.new(self, 55)
35
+ evt_timer(55) do
36
+ p = Thread.current.priority
37
+ Thread.current.priority = p - 10
38
+ Thread.pass
39
+ Thread.current.priority = p
40
+ end
41
+ t.start(100)
42
+
43
+ hidden = Wx::Frame.new nil, -1, "hello"
44
+ hidden.show
45
+ end
46
+ end
47
+ end
48
+
49
+ class Window
50
+
51
+ def initialize server, client, options
52
+ @window = Wx::Frame.new nil, Wx::ID_ANY
53
+ @window.show
54
+ # layout = Wx::BoxSizer.new(Wx::VERTICAL)
55
+ # set_sizer(layout)
56
+ end
57
+
58
+ def << string
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,11 @@
1
+ module Chat; end
2
+
3
+ require 'chat/screen/fox'
4
+
5
+ module Chat::Screen
6
+
7
+ def self.new *args
8
+ Chat::Screen::Fox.new( *args )
9
+ end
10
+
11
+ end
@@ -0,0 +1,72 @@
1
+ module Chat; end
2
+
3
+ require 'dramatis/actor'
4
+
5
+ class Chat::Server
6
+
7
+ include Dramatis::Actor
8
+
9
+ def initialize password
10
+ @password = password
11
+ @groups = {}
12
+ end
13
+
14
+ def connect password
15
+ if password == @password
16
+ Connection.new actor.name
17
+ else
18
+ raise "bad password"
19
+ end
20
+ end
21
+
22
+ def login group, user, client
23
+ if !actor = @groups[group]
24
+ actor = @groups[group] = Group.new( group, user, client )
25
+ else
26
+ actor.login user, client
27
+ end
28
+ actor
29
+ end
30
+
31
+ class Connection
32
+ include Dramatis::Actor
33
+ def initialize server
34
+ @server = server
35
+ end
36
+
37
+ def login group, user, client
38
+ @server.login group, user, client
39
+ end
40
+ end
41
+
42
+ class Group
43
+ include Dramatis::Actor
44
+
45
+ def initialize name, user, client
46
+ @name = name
47
+ @clients = { client => user }
48
+ @cast = interface( actor.name ).continue nil
49
+
50
+ @cast << { :user => user, :client => client, :string => "I'm starting the group" }
51
+ end
52
+
53
+ def login user, client
54
+ @clients[client] = user
55
+ @cast << { :user => user, :client => client, :string => "I'm joining the group" }
56
+ end
57
+
58
+ def logout client
59
+ user = @clients[client]
60
+ @clients.delete client
61
+ @cast << { :user => user, :client => client, :string => "I'm leaving the group" }
62
+ end
63
+
64
+ def << opts
65
+ @clients.each_key do |client|
66
+ ( interface( client ).continue nil ) << opts
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,5 @@
1
+ module Chat; end
2
+
3
+ require 'chat/screen'
4
+ require 'chat/server'
5
+ require 'chat/client'
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "..", "lib" )
4
+
5
+ require 'chat'
6
+
7
+ password = "xyzzy"
8
+ group = "general"
9
+
10
+ screen = Chat::Screen::Fox.new
11
+
12
+ server = Chat::Server.new password
13
+
14
+ joe = Chat::Client.new screen, server, password, group, "joe"
15
+ jane = Chat::Client.new screen, server, password, group, "jane"
16
+ jim = Chat::Client.new screen, server, password, group, "jim"
17
+ sue = Chat::Client.new screen, server, password, group, "sue"
18
+
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "..", "lib" )
4
+
5
+ require 'chat'
6
+ require 'chat/screen/wxs'
7
+
8
+ password = "xyzzy"
9
+ group = "general"
10
+
11
+ screen = Chat::Screen::WX.new
12
+
13
+ server = Chat::Server.new password
14
+
15
+ joe = Chat::Client.new screen, server, password, group, "joe"
16
+ jane = Chat::Client.new screen, server, password, group, "jane"
17
+ jim = Chat::Client.new screen, server, password, group, "jim"
18
+ sue = Chat::Client.new screen, server, password, group, "sue"
19
+
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "lib" )
4
+
5
+ require 'dramatis/actor'
6
+
7
+ class PingPong
8
+
9
+ include Dramatis::Actor
10
+
11
+ def initialize name
12
+ @name = name
13
+ end
14
+
15
+ def pingpong count, partner
16
+ if count == 0
17
+ puts "#{@name}: done"
18
+ else
19
+ if count % 500 == 0 or count % 500 == 1
20
+ puts "#{@name}: pingpong #{count}"
21
+ end
22
+ release( partner ).pingpong count-1, self
23
+ end
24
+ # sleep 0.001
25
+ end
26
+
27
+ end
28
+
29
+ ping = PingPong.new "ping"
30
+ pong = PingPong.new "pong"
31
+
32
+ ping.pingpong ARGV[0].to_i, pong
33
+
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.join( File.dirname(__FILE__), "..", "..", "lib" )
4
+
5
+ require 'dramatis/actor'
6
+
7
+ class PingPong
8
+
9
+ include Dramatis::Actor
10
+
11
+ def initialize name
12
+ actor.enable_call_threading
13
+ @name = name
14
+ end
15
+
16
+ def pingpong count, partner
17
+ if count == 0
18
+ puts "#{@name}: done"
19
+ else
20
+ if count % 500 == 0 or count % 500 == 1
21
+ puts "#{@name}: pingpong #{count}"
22
+ end
23
+ partner.pingpong count-1, self
24
+ end
25
+ # sleep 0.001
26
+ end
27
+
28
+ end
29
+
30
+ ping = PingPong.new "ping"
31
+ pong = PingPong.new "pong"
32
+
33
+ ping.pingpong ARGV[0].to_i, pong
34
+