tidyflash 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 (42) hide show
  1. data/Manifest +40 -0
  2. data/README +4 -0
  3. data/Rakefile +15 -0
  4. data/bin/test_project.axml +19 -0
  5. data/bin/tidyflash +33 -0
  6. data/lib/script/bwlimit.rb +305 -0
  7. data/lib/script/generate +124 -0
  8. data/lib/script/server +4 -0
  9. data/lib/script/server.rb +20 -0
  10. data/lib/tasks/assets.rb +133 -0
  11. data/lib/tasks/demo_config.rb +27 -0
  12. data/lib/tasks/deploy.rb +21 -0
  13. data/lib/tidy/axml.rb +31 -0
  14. data/lib/tidy/compile.rb +97 -0
  15. data/lib/tidy/generate.rb +20 -0
  16. data/lib/tidy/template.rb +84 -0
  17. data/lib/tidy/template_binding.rb +26 -0
  18. data/lib/tidy/templates/air.axml.erb +19 -0
  19. data/lib/tidy/templates/demo_config.as.erb +7 -0
  20. data/lib/tidy_project.rb +26 -0
  21. data/templates/project/project.rb +17 -0
  22. data/templates/project/rakefile.rb +29 -0
  23. data/templates/project/script/fcsh/rakefile.rb +3 -0
  24. data/templates/project/src/app/helpers/Colours.as +1 -0
  25. data/templates/project/src/app/helpers/Debug.as +17 -0
  26. data/templates/project/src/app/helpers/Typography.as +1 -0
  27. data/templates/project/src/app/models/App.as +21 -0
  28. data/templates/project/src/app/models/FlashVars.as +1 -0
  29. data/templates/project/src/app/views/MainView.as +16 -0
  30. data/templates/project/src/app/views/PreloaderView.as +36 -0
  31. data/templates/scaffold/bin/xml/__model.xml +0 -0
  32. data/templates/scaffold/scaffold.rb +41 -0
  33. data/templates/scaffold/src/models/__Model.as +11 -0
  34. data/templates/scaffold/src/views/__model/__ModelDetailView.as +0 -0
  35. data/templates/scaffold/src/views/__model/__ModelListItemView.as +0 -0
  36. data/templates/scaffold/src/views/__model/__ModelListView.as +0 -0
  37. data/templates/swfobject/bin/index.html +16 -0
  38. data/templates/swfobject/bin/js/swfobject.js +5 -0
  39. data/templates/swfobject/swfobject.rb +12 -0
  40. data/test/test_tidy_project.rb +67 -0
  41. data/tidyflash.gemspec +32 -0
  42. metadata +125 -0
data/Manifest ADDED
@@ -0,0 +1,40 @@
1
+ Manifest
2
+ README
3
+ Rakefile
4
+ bin/test_project.axml
5
+ bin/tidyflash
6
+ lib/script/bwlimit.rb
7
+ lib/script/generate
8
+ lib/script/server
9
+ lib/script/server.rb
10
+ lib/tasks/assets.rb
11
+ lib/tasks/demo_config.rb
12
+ lib/tasks/deploy.rb
13
+ lib/tidy/axml.rb
14
+ lib/tidy/compile.rb
15
+ lib/tidy/generate.rb
16
+ lib/tidy/template.rb
17
+ lib/tidy/template_binding.rb
18
+ lib/tidy/templates/air.axml.erb
19
+ lib/tidy/templates/demo_config.as.erb
20
+ lib/tidy_project.rb
21
+ templates/project/project.rb
22
+ templates/project/rakefile.rb
23
+ templates/project/script/fcsh/rakefile.rb
24
+ templates/project/src/app/helpers/Colours.as
25
+ templates/project/src/app/helpers/Debug.as
26
+ templates/project/src/app/helpers/Typography.as
27
+ templates/project/src/app/models/App.as
28
+ templates/project/src/app/models/FlashVars.as
29
+ templates/project/src/app/views/MainView.as
30
+ templates/project/src/app/views/PreloaderView.as
31
+ templates/scaffold/bin/xml/__model.xml
32
+ templates/scaffold/scaffold.rb
33
+ templates/scaffold/src/models/__Model.as
34
+ templates/scaffold/src/views/__model/__ModelDetailView.as
35
+ templates/scaffold/src/views/__model/__ModelListItemView.as
36
+ templates/scaffold/src/views/__model/__ModelListView.as
37
+ templates/swfobject/bin/index.html
38
+ templates/swfobject/bin/js/swfobject.js
39
+ templates/swfobject/swfobject.rb
40
+ test/test_tidy_project.rb
data/README ADDED
@@ -0,0 +1,4 @@
1
+ Following in the footsteps of Ruby On Rails, Processing, _why's Shoes and Luke Bayes' Sprouts library, here is a Flash framework that funnels the brilliance of all these people into a single set of libraries for developing Flash.
2
+ USAGE:
3
+
4
+ tidyproject SomeProject
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('tidyflash', '0.1') do |p|
6
+ p.description = "Tidy Flash - an ActionScript framework for people who love Ruby"
7
+ p.url = "http://github.com/michaelforrest/tidy"
8
+ p.author = "Michael Forrest"
9
+ p.email = "mf@grimaceworks.com"
10
+ p.ignore_pattern = ["tmp/**/*", "script/*", "tasks/**/*"]
11
+ p.development_dependencies = []
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
15
+
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <application xmlns="http://ns.adobe.com/air/application/1.5">
3
+ <id>testproject</id>
4
+ <version>1</version>
5
+ <filename>testproject</filename>
6
+ <initialWindow>
7
+ <content>test_project.swf</content>
8
+ <visible>true</visible>
9
+ <x>400</x>
10
+ <y>50</y>
11
+ <width>1200</width>
12
+ <height>923</height>
13
+ </initialWindow>
14
+ <!--
15
+ <icon>
16
+ <image128x128>icons/128x128/fubuntu_logo_128x128.png</image128x128>
17
+ </icon>
18
+ -->
19
+ </application>
data/bin/tidyflash ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require File.dirname(__FILE__) + '/../lib/tidy_project'
6
+
7
+ def fail_with(opts, message)
8
+ puts "[ERROR] #{message}"
9
+ puts ""
10
+ puts opts
11
+ exit
12
+ end
13
+
14
+ parser = OptionParser.new do |options|
15
+ options.banner = <<-BANNER
16
+ Tidy is an ActionScript framework for people who love Ruby
17
+
18
+ Usage: #{File.basename($0)}
19
+ - adds necessary stuff to project
20
+ BANNER
21
+
22
+ options.separator ""
23
+
24
+ # options.on("-v", "--verbose", "Show what it's doing") do
25
+ # OPTIONS[:verbose] = true
26
+ # end
27
+
28
+
29
+ end
30
+
31
+ puts ">> adding stuff to project"
32
+ fail_with ARGV, "Please specify a project name!" if ARGV.length < 1
33
+ TidyProject.new(ARGV[0])
@@ -0,0 +1,305 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'socket'
5
+ require 'fcntl'
6
+ require 'thread'
7
+
8
+
9
+ # Limits the amount of data sent/recv.
10
+ # It acts as a authorisation-to-sent/recv-data dispenser
11
+ # Whoever wants to send/recv data must call the #dispense method
12
+ # to know how many it should send/recv at that time
13
+ class BwLimiter
14
+ def initialize(rate, ticks)
15
+ @bytes_per_tick = 1.0*rate/ticks
16
+ @hz = 1.0/ticks
17
+ if @bytes_per_tick < 1
18
+ raise "rate too low or ticks too high"
19
+ end
20
+ @bytes_per_tick = @bytes_per_tick.round
21
+ if @bytes_per_tick * ticks != rate
22
+ puts "Adjusting rate to #{@bytes_per_tick * ticks}"
23
+ end
24
+ @last_tick = Time.now
25
+ end
26
+ def dispense
27
+ curr = Time.now
28
+ delta = curr - @last_tick
29
+ if delta < @hz
30
+ sleep(@hz - delta)
31
+ end
32
+ #puts "Releasing #{@bytes_per_tick}. Speed = #{@bytes_per_tick / (Time.now - curr)}"
33
+ @last_tick = curr
34
+ @bytes_per_tick
35
+ end
36
+ end
37
+
38
+ class ConstantBwLimiter < BwLimiter
39
+ def initialize
40
+ end
41
+ def dispense
42
+ 8192
43
+ end
44
+ end
45
+
46
+
47
+
48
+ class BwLimiterProxy
49
+ def self.create_producer_thread(name, socket, socket_mutex,
50
+ queue, queue_mutex, queue_added_cond,
51
+ read_limiter, kill_thread_proc)
52
+ Thread.new {
53
+ read_s = nil
54
+ while (1)
55
+ result = select([socket], nil, [socket], nil)
56
+ if result[0].length > 0
57
+ n_read = read_limiter.dispense
58
+ #puts "#{name} need to read #{n_read}"
59
+ socket_mutex.synchronize {
60
+ read_s = socket.recv(n_read)
61
+ }
62
+ if (read_s.length == 0)
63
+ #puts "#{name} closed"
64
+ kill_thread_proc.call
65
+ break # or Thread.stop
66
+ else
67
+ queue_mutex.synchronize {
68
+ read_s.split(//).each {|i| queue << i}
69
+ #puts "#{name}: read #{read_s.length}"
70
+ queue_added_cond.signal
71
+ }
72
+ end
73
+ elsif result[2].length > 0
74
+ raise "#{name} read error"
75
+ end
76
+ end
77
+ }
78
+ end
79
+
80
+
81
+
82
+ def self.create_consumer_thread(name, socket, socket_mutex,
83
+ queue, queue_mutex, queue_added_cond,
84
+ write_limiter)
85
+ my_queue = nil
86
+ Thread.new{
87
+ while (1)
88
+ queue_mutex.synchronize {
89
+ queue_added_cond.wait(queue_mutex)
90
+ my_queue = queue.clone
91
+ queue.clear
92
+ }
93
+ while (my_queue && my_queue.length > 0)
94
+ result = select(nil, [socket], [socket], nil)
95
+ if result[1].length > 0
96
+ n_write = write_limiter.dispense
97
+ socket_mutex.synchronize {
98
+ n_write = socket.send(my_queue[0..n_write].join, 0)
99
+ }
100
+ my_queue.slice!(0..n_write);
101
+ #puts "REMOTE: written #{n_write}"
102
+ elsif result[2].length > 0
103
+ raise "#{name} send error"
104
+ end
105
+ end
106
+ end
107
+ }
108
+ end
109
+
110
+
111
+
112
+ def self.make_nonblocking(io)
113
+ io.fcntl(Fcntl::F_SETFD, io.fcntl(Fcntl::F_GETFD) | Fcntl::O_NONBLOCK)
114
+ end
115
+
116
+
117
+ def self.make_proc_kill_thread(t_parent)
118
+ proc{t_parent[:thread_list].each {|t|
119
+ t.kill if Thread.current != t
120
+ #puts "Killed: #{t.inspect}";
121
+ }
122
+ }
123
+ end
124
+
125
+
126
+ attr_reader :is_global_limit
127
+ attr_reader :input_rate
128
+ attr_reader :output_rate
129
+ attr_reader :ticks
130
+ attr_reader :input_limiter
131
+ attr_reader :output_limiter
132
+
133
+ def session(l_socket, r_socket)
134
+ [l_socket, r_socket].each {|io|
135
+ BwLimiterProxy.make_nonblocking io
136
+ }
137
+
138
+ proc_kill_thread = BwLimiterProxy.make_proc_kill_thread(Thread.current)
139
+
140
+ if @is_global_limit
141
+ input_limiter = @input_limiter
142
+ output_limiter = @output_limiter
143
+ else
144
+ t_current = Thread.current;
145
+ input_limiter = BwLimiter.new(@input_rate, @ticks)
146
+ output_limiter = BwLimiter.new(@output_rate, @ticks)
147
+ end
148
+ local_input_limiter = ConstantBwLimiter.new
149
+ local_output_limiter = ConstantBwLimiter.new
150
+
151
+ outgoing_queue = [] #from l->r
152
+ outgoing_mutex = Mutex.new
153
+ outgoing_produced = ConditionVariable.new
154
+
155
+ incoming_queue = [] #from r->l
156
+ incoming_mutex = Mutex.new
157
+ incoming_produced = ConditionVariable.new
158
+
159
+ l_socket_mutex = Mutex.new
160
+ r_socket_mutex = Mutex.new
161
+
162
+ t_outgoing_producer =
163
+ BwLimiterProxy.create_producer_thread("LOCAL", l_socket, l_socket_mutex,
164
+ outgoing_queue, outgoing_mutex,
165
+ outgoing_produced,
166
+ local_output_limiter,
167
+ proc_kill_thread)
168
+ t_incoming_producer =
169
+ BwLimiterProxy.create_producer_thread("REMOTE", r_socket, r_socket_mutex,
170
+ incoming_queue, incoming_mutex,
171
+ incoming_produced,
172
+ input_limiter,
173
+ proc_kill_thread)
174
+ t_outgoing_consumer =
175
+ BwLimiterProxy.create_consumer_thread("REMOTE", r_socket, r_socket_mutex,
176
+ outgoing_queue, outgoing_mutex,
177
+ outgoing_produced,
178
+ output_limiter)
179
+ t_incoming_consumer =
180
+ BwLimiterProxy.create_consumer_thread("LOCAL", l_socket, l_socket_mutex,
181
+ incoming_queue, incoming_mutex,
182
+ incoming_produced,
183
+ local_input_limiter)
184
+
185
+ t_current = Thread.current
186
+ t_current[:thread_list] = [t_outgoing_producer, t_incoming_producer,
187
+ t_outgoing_consumer, t_incoming_consumer]
188
+ #t_current[:thread_list].each{|t| puts "Threads: #{t.inspect}"}
189
+
190
+ t_current[:thread_list].each {|t|
191
+ t.join;
192
+ #puts "Joined: #{t.inspect}";
193
+ }
194
+ l_socket.close
195
+ r_socket.close
196
+ #puts "Exiting cleanly"
197
+ end
198
+
199
+
200
+ def initialize(input_rate, output_rate, is_global_limit, ticks)
201
+ @input_rate = input_rate
202
+ @output_rate = output_rate
203
+ @ticks = ticks
204
+ if @is_global_limit = is_global_limit
205
+ @input_limiter = BwLimiter.new(@input_rate, @ticks)
206
+ @output_limiter = BwLimiter.new(@output_rate, @ticks)
207
+ end
208
+ end
209
+ end
210
+
211
+
212
+ def print_help
213
+ puts <<-EOF
214
+ # #{$0} [options] rhost rport
215
+ #
216
+ # --lhost x listen to the interface x (def: localhost)
217
+ # --lport x listen to port x (def: 8119)
218
+ # --outgoing-rate x
219
+ # -o x output at x KBps (def: 5)
220
+ # --incoming-rate x
221
+ # -i x accepts input at xKBps (def: 5)
222
+ # --global-limit
223
+ # -g if set, the rate is for total rate (def: the rate is per connection)
224
+ # --ticks
225
+ # -t ticks per second, higher more accurate but consumes more cpu (def: 100)
226
+ # --help
227
+ # -h this page
228
+ # rhost host to connect to
229
+ # rport port to connect to
230
+ EOF
231
+ end
232
+
233
+
234
+
235
+ if $0 == __FILE__
236
+ require 'getoptlong'
237
+
238
+ if ARGV.length < 2
239
+ print_help
240
+ exit
241
+ end
242
+ opts = GetoptLong.new(["--lhost", GetoptLong::REQUIRED_ARGUMENT ],
243
+ ["--lport", GetoptLong::REQUIRED_ARGUMENT ],
244
+ ["--outgoing-rate", "-o", GetoptLong::REQUIRED_ARGUMENT ],
245
+ ["--incoming-rate", "-i", GetoptLong::REQUIRED_ARGUMENT ],
246
+ ["--outgoing-rate-byte", "--orb", GetoptLong::REQUIRED_ARGUMENT ],
247
+ ["--incoming-rate-byte", "--irb", GetoptLong::REQUIRED_ARGUMENT ],
248
+ ["--global-limit", "-g", GetoptLong::NO_ARGUMENT],
249
+ ["--ticks", "-t", GetoptLong::REQUIRED_ARGUMENT],
250
+ ["--help", "-h", GetoptLong::NO_ARGUMENT])
251
+ hopts = {}
252
+ opts.each {|opt, arg|
253
+ hopts[opt] = arg
254
+ }
255
+ if ARGV.length != 2
256
+ print_help
257
+ end
258
+
259
+
260
+ LPORT = (hopts["--lport"] || 8119).to_i
261
+ LHOST = hopts["--lhost"] || "localhost"
262
+ OUTGOING_RATE = (hopts["--outgoing-rate"] || 5).to_i * 1024
263
+ INCOMING_RATE = (hopts["--incoming-rate"] || 5).to_i * 1024
264
+ IS_GLOBAL_LIMIT = if hopts["--global-limit"] then true else false end
265
+ TICKS = (hopts["--ticks"] || 100).to_i
266
+ RHOST = ARGV[0]
267
+ RPORT = ARGV[1].to_i
268
+
269
+ if hopts["--outgoing-rate-byte"]
270
+ OUTGOING_RATE = hopts["--outgoing-rate-byte"].to_i
271
+ end
272
+ if hopts["--incoming-rate-byte"]
273
+ INCOMING_RATE = hopts["--incoming-rate-byte"].to_i
274
+ end
275
+
276
+ puts "LPORT=#{LPORT}"
277
+ puts "LHOST=#{LHOST}"
278
+ puts "OUTGOING_RATE=#{OUTGOING_RATE}"
279
+ puts "INCOMING_RATE=#{INCOMING_RATE}"
280
+ puts "TICKS=#{TICKS}"
281
+ puts "IS_GLOBAL_LIMIT=#{IS_GLOBAL_LIMIT.to_s}"
282
+ puts "RHOST=#{RHOST}"
283
+ puts "RPORT=#{RPORT}"
284
+
285
+ threads = []
286
+ threads_mutex = Mutex.new
287
+ proxy = BwLimiterProxy.new(INCOMING_RATE, OUTGOING_RATE, IS_GLOBAL_LIMIT, TICKS)
288
+ server = TCPServer.new(LHOST, LPORT)
289
+ #server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
290
+ puts "Ready"
291
+ while (local_socket = server.accept)
292
+ begin
293
+ remote_socket = TCPSocket.new(RHOST, RPORT)
294
+ t = Thread.new {
295
+ proxy.session(local_socket, remote_socket)
296
+ threads_mutex.synchronize { threads.delete_if{|t| Thread.current == t}}
297
+ puts "Now serving #{threads.size} connections"
298
+ }
299
+ threads_mutex.synchronize { threads << t }
300
+ puts "Now serving #{threads.size} connections"
301
+ rescue => e
302
+ p e
303
+ end
304
+ end
305
+ end
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'activesupport'
4
+ LANGUAGE = 'as3' #TODO: un-hard-code
5
+ SCRIPT_PATH = File.join("script", LANGUAGE)
6
+ def available_templates
7
+ Dir.entries(SCRIPT_PATH).collect{|e| e unless e[0]==46}.compact
8
+ end
9
+
10
+ module LBi
11
+ require 'erb'
12
+ require 'fileutils'
13
+ class Template
14
+ attr_reader :args
15
+ def initialize(params)
16
+ @template_id = params[:template_id]
17
+ @force = params[:force]
18
+ @args = params[:args].collect{|arg| arg unless arg.match("--")}
19
+
20
+ create_template_binding
21
+ copy_files if @template_binding.valid?
22
+ end
23
+ def create_template_binding
24
+ require template_class
25
+ # the get_template_binding method is placed
26
+ # in the included template class
27
+ @template_binding = get_template_binding(self)
28
+ @template_binding.init!
29
+ end
30
+
31
+ def template_path
32
+ File.join(SCRIPT_PATH,@template_id)
33
+ end
34
+
35
+ def template_class
36
+ File.join(template_path,"#{@template_id}.rb")
37
+ end
38
+
39
+ def copy_files
40
+ pattern = File.join(template_path,"**/*")
41
+ files = Dir.glob(pattern)
42
+ files.each do |filename|
43
+ copy_file(filename) unless filename == template_class
44
+ end
45
+ end
46
+
47
+ def copy_file(filename)
48
+ if File.directory?(filename)
49
+
50
+ make_dirs(get_destination filename)
51
+ return
52
+ end
53
+ contents = IO.read(filename)
54
+ destination = get_destination(filename)
55
+ make_dirs(File.split(destination)[0])
56
+
57
+ result = File.extname(filename) == ".erb" ? contents : ERB.new(contents,0,"%").result(@template_binding.get_binding)
58
+ force = @force unless @force.nil?
59
+ if File.exists?(destination)
60
+ if(force.nil?)
61
+ puts "overwrite #{destination}? (yN)"
62
+ force = $stdin.gets.chomp.downcase == "y"
63
+ end
64
+ unless force
65
+ puts "skipping #{destination}"
66
+ else
67
+ File.delete(destination)
68
+ write_result(result,destination)
69
+ end
70
+ else
71
+ write_result(result,destination)
72
+ end
73
+ end
74
+
75
+ def write_result result,destination
76
+ File.open(destination,'a') do |file|
77
+ file << result
78
+ end
79
+ puts("created " + destination)
80
+ end
81
+
82
+ def make_dirs(dir)
83
+ FileUtils.mkdir_p(dir) unless File.exists? dir
84
+ end
85
+
86
+ def get_destination(file)
87
+ @template_binding.get_destination file.gsub(template_path,".")
88
+ end
89
+ end
90
+ class TemplateBinding
91
+ def initialize(template)
92
+ @template = template
93
+ @is_valid = true
94
+ end
95
+ def init!
96
+ #override this method to do extra curricular template activities
97
+ end
98
+ def valid?
99
+ @is_valid
100
+ end
101
+ def get_binding
102
+ return binding
103
+ end
104
+ def get_destination path
105
+ path
106
+ end
107
+ #COMMON stuff for templates
108
+ def credit
109
+ "Generated with Tidy Flash"
110
+ end
111
+ end
112
+ end
113
+ params = {:force=>ARGV.find{|a| a=="--force"}!=nil, :template_id=>ARGV.shift, :args=>ARGV}
114
+
115
+ unless params[:template_id].nil?
116
+ LBi::Template.new(params)
117
+ else
118
+ puts <<-MSG
119
+ Please provide a template name, e.g.
120
+ $ ruby script/lbi/generate carousel
121
+ Available templates: #{available_templates.join(",")}
122
+ MSG
123
+ end
124
+
data/lib/script/server ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ ./script/server.rb &
3
+ ./script/bwlimit.rb --lhost localhost --lport 2001 -i 99 -o 99 localhost 2000 &
4
+ open http://localhost:2001
@@ -0,0 +1,20 @@
1
+ #!/usr/local/bin/ruby
2
+ require 'webrick'
3
+ include WEBrick
4
+
5
+ s = HTTPServer.new(
6
+ :Port => 2000,
7
+ :DocumentRoot => File.join(File.dirname(__FILE__), "..", "bin"),
8
+ :MimeTypes => {:js=>"text/javascript"}
9
+ )
10
+
11
+ ## mount subdirectories
12
+ #s.mount("/ipr", HTTPServlet::FileHandler, "/proj/ipr/public_html")
13
+ #s.mount("/~gotoyuzo",
14
+ # HTTPServlet::FileHandler, "/home/gotoyuzo/public_html",
15
+ # true) #<= allow to show directory index.
16
+ #system_mime_table = Utils::load_mime_types('/etc/mime.types')
17
+
18
+
19
+ trap("INT"){ s.shutdown }
20
+ s.start()
@@ -0,0 +1,133 @@
1
+ require 'activesupport'
2
+ namespace :assets do
3
+ desc "Build list of desktop images"
4
+ task :desktop do
5
+ catalog_file "bin/system/desktop_backgrounds", "DesktopCatalog"
6
+ end
7
+
8
+ desc "App-related assets"
9
+ task :apps do
10
+ Dir.chdir("src/plugins/apps/firefox/") do
11
+ asset_file ".", "FirefoxLibrary", :package=>'plugins.apps.firefox.assets'
12
+ end
13
+ end
14
+
15
+ desc "Create boot classes"
16
+ task :boot do
17
+ asset_file "boot", "BootLibrary"
18
+ asset_file "boot/avatars", "Avatars"
19
+ asset_file "boot/icons", "BootIcons"
20
+ end
21
+
22
+ desc "mouse cursors"
23
+ task :cursors do
24
+ asset_file "cursors", "CursorLibrary"
25
+ end
26
+
27
+ desc "Create menu icon classes"
28
+ task :menu do
29
+ Dir.chdir("common/plugins/menus") do
30
+ asset_file '.', 'MessagingServicesLibrary', :package=>'plugins.menus.assets'
31
+ end
32
+ end
33
+
34
+ desc "Create menu panel icon classes"
35
+ task :panels do
36
+ asset_file "panels", "PanelLibrary"
37
+ end
38
+
39
+ desc "Create UI library"
40
+ task :ui do
41
+ asset_file "ui", "UILibrary"
42
+ asset_file "ui/scrollbar", "OverlayScrollbarLibrary"
43
+ end
44
+
45
+ desc "testing assets"
46
+ task :testing do
47
+ asset_file "testing", "TestingLibrary"
48
+ end
49
+
50
+ desc 'launcher assets'
51
+ task :launcher do
52
+ Dir.chdir("common/plugins/launcher") do
53
+ asset_file '.', 'LauncherLibrary', :package=>'plugins.launcher.assets'
54
+ end
55
+ end
56
+
57
+ desc 'dash-related assets'
58
+ task :dash do
59
+ Dir.chdir("common/plugins/dash") do
60
+ asset_file '.', 'DashLibrary', :package=>'plugins.dash.assets'
61
+ asset_file './categories', 'DashCategoriesLibrary', :package=>'plugins.dash.assets.categories'
62
+ asset_file './groupicons', 'DashGroupIconsLibrary', :package=>'plugins.dash.assets.groupicons'
63
+ asset_file './menuicons', 'DashMenuIconsLibrary', :package=>'plugins.dash.assets.menuicons'
64
+
65
+ end
66
+ end
67
+
68
+ desc 'hud-related assets'
69
+ task :hud do
70
+ asset_file 'hud', 'HUDLibrary'
71
+ end
72
+
73
+ desc 'unr-related assets'
74
+ task :unr do
75
+ asset_file 'unr', "UNRLibrary"
76
+ end
77
+
78
+ desc "window assets"
79
+ task :theme do
80
+ Dir.entries("common/themes/").each do |entry|
81
+
82
+ if File.directory?("common/themes/#{entry}") && (entry =~ /^\./).nil? && entry != "fonts"
83
+ puts "updating theme library for #{entry} to #{entry.classify}"
84
+ Dir.chdir("common/themes/#{entry}") do
85
+ asset_file ".", "#{entry.classify}Library", :package=>"themes.#{entry}.assets"
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ def asset_file dir, class_name, options={}
92
+ Dir.chdir("assets/#{dir}") do
93
+ File.open("#{class_name}.as","w") do |file|
94
+ file << <<-END
95
+ package #{options[:package] || dir.gsub("/",".")}{
96
+ public class #{class_name}{
97
+ END
98
+ %w[.png .jpg .swf].each do |suffix|
99
+ add_entries file, suffix
100
+ end
101
+ file << "}}"
102
+ end
103
+ end
104
+
105
+ end
106
+ def add_entries file, suffix
107
+ Dir.entries(".").select{ |f| f.match(suffix) }.each do |icon|
108
+ file << "[Embed(source='#{icon}')] "
109
+ file << "public static var #{icon.gsub(suffix,"").gsub("-","_")}: Class;\n"
110
+ puts icon
111
+ end
112
+ end
113
+
114
+ def catalog_file dir, class_name
115
+ File.open("assets/catalogs/#{class_name}.as","w") do |file|
116
+ file << <<-END
117
+ package catalogs {
118
+ // this file is automatically generated with rake assets:desktop
119
+ public class DesktopCatalog {
120
+ public static var BACKGROUNDS : Array = [
121
+ END
122
+
123
+ file << Dir.entries(dir).map{|f| "'#{f}'" unless f =~ /^\./ }.compact.join(",")
124
+
125
+ file << <<-END
126
+ ];
127
+ }
128
+ }
129
+ END
130
+ end
131
+ end
132
+
133
+ end