jrubyfx-fxmlloader 0.2-java → 0.3-java
Sign up to get free protection for your applications and to get access to all the features.
- data/README +15 -3
- data/Rakefile +1 -1
- data/lib/FXMLLoader-j8.jar +0 -0
- data/lib/fxmlloader/elts.rb +68 -59
- data/lib/fxmlloader/fxml_jit_info.rb +158 -0
- data/lib/fxmlloader/j8_expression_value.rb +148 -101
- data/lib/fxmlloader/real_elts.rb +195 -184
- data/lib/fxmlloader/rorba.rb +3 -29
- data/lib/fxmlloader/rrba.rb +161 -399
- data/lib/fxmlloader/value_elts.rb +13 -23
- data/lib/jrubyfx-fxmlloader.rb +240 -124
- metadata +6 -5
data/README
CHANGED
@@ -1,5 +1,17 @@
|
|
1
|
-
|
1
|
+
# JRubyFX-FxmlLoader
|
2
2
|
|
3
|
-
|
3
|
+
JRubyFX-FxmlLoader is the JIT-enabled FXML parser for the JRubyFX project based
|
4
|
+
on the official OpenJDK 8 FXML parser. FxmlLoader strives to be a nearly drop-in
|
5
|
+
replacement FxmlLoader, only differing in JRuby compatibility.
|
4
6
|
|
5
|
-
|
7
|
+
At this point,
|
8
|
+
most code is directly copied from OpenJDK and converted to ruby via regexes and
|
9
|
+
as such is far from idiomatic ruby. The JIT compiler is also a work in progress.
|
10
|
+
|
11
|
+
If you would like to help clean up the code please do but be careful about breaking
|
12
|
+
FXML. Any 100% standard Java FXML document should work *identically* when run as a JRuby FXML document and
|
13
|
+
vice-versa with the exception of JRuby support (like ruby classes & controllers).
|
14
|
+
|
15
|
+
Use with JRubyFX!
|
16
|
+
|
17
|
+
rake gem to build. Note that half of this project is java and must be compiled.
|
data/Rakefile
CHANGED
data/lib/FXMLLoader-j8.jar
CHANGED
Binary file
|
data/lib/fxmlloader/elts.rb
CHANGED
@@ -49,16 +49,19 @@ class Element
|
|
49
49
|
collection = false;
|
50
50
|
end
|
51
51
|
end
|
52
|
-
dputs callz + "Is it a collection? #{collection.inspect} <= #{@value.java_class}"
|
53
52
|
return collection;
|
54
53
|
end
|
55
54
|
|
56
|
-
def add(element)
|
57
|
-
dputs callz + "about to add #{element} to #{value.to_java}"
|
55
|
+
def add(element, prop_name=nil, rputs_elt=nil)
|
58
56
|
# If value is a list, add element to it; otherwise, get the value
|
59
57
|
# of the default property, which is assumed to be a list and add
|
60
58
|
# to that (coerce to the appropriate type)
|
61
59
|
if (@value.kind_of?(Enumerable) || @value.java_kind_of?(java.util.List))
|
60
|
+
if prop_name == nil
|
61
|
+
rputs value, "add(#{rget(element)||element.inspect})"
|
62
|
+
else
|
63
|
+
rputs @parent.value, "get#{prop_name[0].upcase}#{prop_name[1..-1]}.add(#{rputs_elt || rget(element)||element.inspect})"
|
64
|
+
end
|
62
65
|
value.to_java
|
63
66
|
else
|
64
67
|
type = value.java_class
|
@@ -69,10 +72,11 @@ class Element
|
|
69
72
|
list = getProperties[defaultPropertyName]
|
70
73
|
|
71
74
|
# Coerce the element to the list item type
|
72
|
-
if (!Map.java_class.assignable_from?(type))
|
75
|
+
if (!java.util.Map.java_class.assignable_from?(type))
|
73
76
|
listType = @valueAdapter.getGenericType(defaultPropertyName);
|
74
77
|
element = RubyWrapperBeanAdapter.coerce(element, RubyWrapperBeanAdapter.getListItemType(listType));
|
75
78
|
end
|
79
|
+
rputs @value, "get#{defaultPropertyName[0].upcase}#{defaultPropertyName[1..-1]}.add(#{rget(element)||element.inspect})"
|
76
80
|
list = list.to_java if list.class == Java::JavaObject
|
77
81
|
list
|
78
82
|
end.add(element)
|
@@ -94,38 +98,17 @@ class Element
|
|
94
98
|
end
|
95
99
|
|
96
100
|
def updateValue(value)
|
97
|
-
dputs callz + "Updating value from #{@value} to #{value.class}"
|
98
101
|
@value = value;
|
99
102
|
@valueAdapter = nil;
|
100
103
|
end
|
101
104
|
|
102
105
|
def isTyped()
|
103
|
-
|
104
|
-
dp @value.class
|
105
|
-
dp @value
|
106
|
-
q = !(@value.java_kind_of? Java::java.util.Map or @value.is_a? Hash );
|
107
|
-
dputs callz + "type result: #{q.inspect}"
|
108
|
-
q
|
106
|
+
!(@value.java_kind_of? Java::java.util.Map or @value.is_a? Hash )
|
109
107
|
end
|
110
108
|
|
111
109
|
def getValueAdapter()
|
112
110
|
if (@valueAdapter == nil)
|
113
|
-
|
114
|
-
dprint callz
|
115
|
-
dprint @value
|
116
|
-
dputs @value.class
|
117
|
-
dputs caller
|
118
|
-
if @value.class.to_s == "Java::JavafxFxml::ObjectBuilder"
|
119
|
-
dputs caller
|
120
|
-
end
|
121
|
-
if @value.is_a? java.lang.Object
|
122
|
-
dputs callz + "trying to call wrapper"
|
123
|
-
@valueAdapter = RubyWrapperBeanAdapter.new(@value);
|
124
|
-
else
|
125
|
-
dputs callz + "trying to call ruby object wrapper"
|
126
|
-
@valueAdapter = RubyObjectWrapperBeanAdapter.new(@value)
|
127
|
-
end
|
128
|
-
dputs callz + "got"
|
111
|
+
@valueAdapter = RubyWrapperBeanAdapter.for(@value)
|
129
112
|
end
|
130
113
|
return @valueAdapter;
|
131
114
|
end
|
@@ -172,7 +155,6 @@ class Element
|
|
172
155
|
if (@loadListener != nil)
|
173
156
|
@loadListener.readEventHandlerAttribute(localName, value);
|
174
157
|
end
|
175
|
-
dputs callz + "found eventHandler prefix #{prefix}, #{localName}, #{value}"
|
176
158
|
eventHandlerAttributes <<(Attribute.new(localName, nil, value));
|
177
159
|
else
|
178
160
|
i = localName.rindex('.');
|
@@ -183,15 +165,12 @@ class Element
|
|
183
165
|
@loadListener.readPropertyAttribute(localName, nil, value);
|
184
166
|
end
|
185
167
|
|
186
|
-
dputs callz + "found property attrib #{prefix}, #{localName}, #{value}"
|
187
168
|
instancePropertyAttributes << (Attribute.new(localName, nil, value));
|
188
169
|
else
|
189
170
|
# The attribute represents a static property
|
190
171
|
name = localName[(i + 1)..-1];
|
191
172
|
sourceType = parentLoader.getType(localName[0, i]);
|
192
173
|
|
193
|
-
dputs callz + "found static property #{prefix}, #{localName}, #{value}"
|
194
|
-
dputs callz + "and its #{sourceType}, #{staticLoad}"
|
195
174
|
if (sourceType != nil)
|
196
175
|
if (@loadListener != nil)
|
197
176
|
@loadListener.readPropertyAttribute(name, sourceType, value);
|
@@ -217,7 +196,6 @@ class Element
|
|
217
196
|
def processPropertyAttribute(attribute)
|
218
197
|
value = attribute.value;
|
219
198
|
if (isBindingExpression(value))
|
220
|
-
dputs callz + "is a binding !"
|
221
199
|
# Resolve the expression
|
222
200
|
|
223
201
|
if (attribute.sourceType != nil)
|
@@ -235,38 +213,28 @@ class Element
|
|
235
213
|
end
|
236
214
|
|
237
215
|
value = value[2..-2] # TODO: BINDING_EXPRESSION_PREFIX == ${
|
238
|
-
|
216
|
+
#value.length() - 1];
|
239
217
|
# TODO: this only works for 7, not 8
|
240
|
-
dputs "getting expression value of '#{value}' with #{parentLoader.namespace}"
|
241
218
|
expression = Expression.valueOf(value);
|
242
|
-
dputs callz + "got the expression as '#{expression}'"
|
243
|
-
dp expression
|
244
219
|
# Create the binding
|
245
220
|
targetAdapter = RubyWrapperBeanAdapter.new(@value);
|
246
|
-
dputs callz + "target adapter is #{targetAdapter} from #{value}"
|
247
221
|
propertyModel = targetAdapter.getPropertyModel(attribute.name).to_java
|
248
222
|
type = targetAdapter.getType(attribute.name);
|
249
|
-
dputs callz + "prop model is #{propertyModel.inspect} and type is #{type.inspect}"
|
250
223
|
if (propertyModel.is_a? Property)
|
251
|
-
|
224
|
+
rputs @value, "#{attribute.name}Property.bind(RRExpressionValue.new(__local_namespace, Java::org.jruby.jfx8.Expression.valueOf(#{value.inspect}), Java::#{type.name.gsub(/[\$\.]/, "::")}.java_class))"
|
252
225
|
#expression.value_property.addListener(JRExpressionTargetMapping.new(expression, getProperties(), Expression.split(value)));
|
253
226
|
( propertyModel).bind(RRExpressionValue.new(parentLoader.namespace, expression, type));
|
254
|
-
dputs callz + "bound!"
|
255
227
|
end
|
256
228
|
elsif (isBidirectionalBindingExpression(value))
|
257
229
|
raise UnsupportedOperationException.new("This feature is not currently enabled.");
|
258
230
|
else
|
259
|
-
dputs callz + "processing 3 for #{attribute.sourceType}, #{attribute.name}, #{value}"
|
260
231
|
processValue3(attribute.sourceType, attribute.name, value);
|
261
232
|
end
|
262
233
|
end
|
263
234
|
|
264
235
|
def isBindingExpression(aValue)
|
265
|
-
dputs callz + "checking if '#{aValue}' is a binding prefix..."
|
266
236
|
# TODO: BINDING_EXPRESSION_PREFIX == ${
|
267
|
-
|
268
|
-
dputs callz + "it is? #{q.inspect}"
|
269
|
-
q
|
237
|
+
aValue.start_with?("${") && aValue.end_with?(FXL::BINDING_EXPRESSION_SUFFIX);
|
270
238
|
end
|
271
239
|
|
272
240
|
def isBidirectionalBindingExpression(aValue)
|
@@ -279,7 +247,6 @@ class Element
|
|
279
247
|
processed = false;
|
280
248
|
#process list or array first
|
281
249
|
if (sourceType == nil && isTyped())
|
282
|
-
dputs callz + "getting value adptr"
|
283
250
|
lvalueAdapter = getValueAdapter();
|
284
251
|
type = lvalueAdapter.getType(propertyName);
|
285
252
|
|
@@ -288,9 +255,8 @@ class Element
|
|
288
255
|
dp sourceType, propertyName, aValue
|
289
256
|
dp lvalueAdapter
|
290
257
|
dp caller
|
291
|
-
raise
|
258
|
+
raise("Property \"" + propertyName + "\" does not exist" + " or is read-only.");
|
292
259
|
end
|
293
|
-
dputs "checking assignable"
|
294
260
|
if (List.java_class.assignable_from?(type) && lvalueAdapter.read_only?(propertyName))
|
295
261
|
populateListFromString(lvalueAdapter, propertyName, aValue);
|
296
262
|
processed = true;
|
@@ -299,11 +265,8 @@ class Element
|
|
299
265
|
processed = true;
|
300
266
|
end
|
301
267
|
end
|
302
|
-
dputs callz + "276"
|
303
268
|
if (!processed)
|
304
|
-
dputs callz + "Must appky it"
|
305
269
|
applyProperty(propertyName, sourceType, resolvePrefixedValue(aValue));
|
306
|
-
dputs callz + "280"
|
307
270
|
processed = true;
|
308
271
|
end
|
309
272
|
return processed;
|
@@ -336,7 +299,11 @@ class Element
|
|
336
299
|
return aValue;
|
337
300
|
else
|
338
301
|
begin
|
339
|
-
|
302
|
+
if $JRUBYFX_AOT_COMPILING
|
303
|
+
return RelativeFXMLString.new(aValue, URL.new(parentLoader.location, aValue).to_s)
|
304
|
+
else
|
305
|
+
return (aValue[0] == '/') ? classLoader.getResource(aValue[1..-1]).to_s : URL.new(parentLoader.location, aValue).to_s
|
306
|
+
end
|
340
307
|
rescue MalformedURLException => e
|
341
308
|
dp e
|
342
309
|
dputs "#{parentLoader.location} + /+ #{aValue}"
|
@@ -375,10 +342,8 @@ class Element
|
|
375
342
|
# The attribute value is nil
|
376
343
|
return nil;
|
377
344
|
end
|
378
|
-
dputs callz + "Getting expression '#{aValue}'"
|
379
345
|
# remove all nils, them add one in at the end so [0] returns nil if empty
|
380
346
|
q = (KeyPath.parse(aValue).map{|i|parentLoader.namespace[i]} - [nil] + [nil])[0]
|
381
|
-
dputs callz + "Parsed Expression! #{q};;;;#{q.inspect}"
|
382
347
|
return q
|
383
348
|
end
|
384
349
|
return aValue;
|
@@ -482,7 +447,6 @@ class Element
|
|
482
447
|
if (attrValue.length() == 0)
|
483
448
|
raise LoadException.new("Missing expression reference.");
|
484
449
|
end
|
485
|
-
dputs callz + "exprValue!' #{attrValue}'"
|
486
450
|
expression = Expression.get(@namespace, KeyPath.parse(attrValue));
|
487
451
|
if (expression.is_a? EventHandler)
|
488
452
|
eventHandler = expression;
|
@@ -490,12 +454,12 @@ class Element
|
|
490
454
|
|
491
455
|
end
|
492
456
|
if (eventHandler == nil)
|
493
|
-
if (attrValue.length() == 0 ||
|
457
|
+
if (attrValue.length() == 0 || parentLoader.scriptEngine == nil)
|
494
458
|
raise LoadException.new("Error resolving " + attribute.name + "='" + attribute.value +
|
495
459
|
"', either the event handler is not in the Namespace or there is an error in the script.");
|
496
460
|
end
|
497
461
|
|
498
|
-
eventHandler = ScriptEventHandler.new(attrValue,
|
462
|
+
eventHandler = ScriptEventHandler.new(attrValue, parentLoader.scriptEngine);
|
499
463
|
end
|
500
464
|
# Add the handler
|
501
465
|
if (eventHandler != nil)
|
@@ -546,6 +510,7 @@ end
|
|
546
510
|
|
547
511
|
class EventHandlerWrapper
|
548
512
|
include EventHandler
|
513
|
+
attr_reader :funcName
|
549
514
|
def initialize(ctrl, funcName)
|
550
515
|
@ctrl = ctrl
|
551
516
|
@funcName = funcName
|
@@ -558,7 +523,51 @@ class EventHandlerWrapper
|
|
558
523
|
@ctrl.send(@funcName, eventArgs)
|
559
524
|
end
|
560
525
|
else
|
561
|
-
|
526
|
+
puts "Warning: method #{@funcName} was not found on controller #{@ctrl}"
|
527
|
+
end
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
class ScriptEventHandler
|
532
|
+
include EventHandler
|
533
|
+
attr_reader :script, :scriptEngine
|
534
|
+
def initialize(script, scriptEngine)
|
535
|
+
@script = script;
|
536
|
+
@scriptEngine = scriptEngine;
|
537
|
+
end
|
538
|
+
|
539
|
+
def handle(event)
|
540
|
+
# Don't pollute the page namespace with values defined in the script
|
541
|
+
engineBindings = @scriptEngine.getBindings(ScriptContext::ENGINE_SCOPE);
|
542
|
+
localBindings = @scriptEngine.createBindings();
|
543
|
+
localBindings.put(FXL::EVENT_KEY, event);
|
544
|
+
@scriptEngine.setBindings(localBindings, ScriptContext::ENGINE_SCOPE);
|
545
|
+
|
546
|
+
# Execute the script
|
547
|
+
begin
|
548
|
+
@scriptEngine.eval(@script);
|
549
|
+
rescue ScriptException => exception
|
550
|
+
raise exception
|
562
551
|
end
|
552
|
+
|
553
|
+
# Restore the original bindings
|
554
|
+
@scriptEngine.setBindings(engineBindings, ScriptContext::ENGINE_SCOPE);
|
563
555
|
end
|
564
|
-
end
|
556
|
+
end
|
557
|
+
|
558
|
+
class RelativeFXMLString < String
|
559
|
+
alias :super_inspect :inspect
|
560
|
+
def initialize(str, rel)
|
561
|
+
super(rel)
|
562
|
+
@rel = str
|
563
|
+
end
|
564
|
+
def inspect
|
565
|
+
"java.net.URL.new(__local_namespace['location'], #{@rel.inspect}).to_s"
|
566
|
+
end
|
567
|
+
def to_s
|
568
|
+
super
|
569
|
+
end
|
570
|
+
def class()
|
571
|
+
String
|
572
|
+
end
|
573
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# * Copyright (c) 2013 Patrick Plenefisch
|
2
|
+
# * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
3
|
+
# *
|
4
|
+
# * This code is free software; you can redistribute it and/or modify it
|
5
|
+
# * under the terms of the GNU General Public License version 2 only, as
|
6
|
+
# * published by the Free Software Foundation. Oracle designates this
|
7
|
+
# * particular file as subject to the "Classpath" exception as provided
|
8
|
+
# * by Oracle in the LICENSE file that accompanied this code.
|
9
|
+
# *
|
10
|
+
# * This code is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
12
|
+
# * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
13
|
+
# * version 2 for more details (a copy is included in the LICENSE file that
|
14
|
+
# * accompanied this code).
|
15
|
+
# *
|
16
|
+
# * You should have received a copy of the GNU General Public License version
|
17
|
+
# * 2 along with this work; if not, write to the Free Software Foundation,
|
18
|
+
# * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
19
|
+
# *
|
20
|
+
|
21
|
+
require 'digest/sha1'
|
22
|
+
require 'fileutils'
|
23
|
+
|
24
|
+
def javafx
|
25
|
+
Java::javafx
|
26
|
+
end
|
27
|
+
|
28
|
+
Infinity = 1.0/0.0
|
29
|
+
|
30
|
+
class FxmlJitInfo
|
31
|
+
include JRubyFX
|
32
|
+
def self.hash(file)
|
33
|
+
Digest::SHA1.hexdigest(File.read file)
|
34
|
+
end
|
35
|
+
def self.load_aot(file, cache, validate = true)
|
36
|
+
if validate
|
37
|
+
hash = hash(file)
|
38
|
+
f_hash = File.open(cache, "r", &:readline).strip
|
39
|
+
return false if "# #{hash} encoding: utf-8" != f_hash
|
40
|
+
end
|
41
|
+
hash = Digest::SHA1.hexdigest(File.basename file)
|
42
|
+
require cache
|
43
|
+
JRubyFX::GeneratedAssets.const_get("AOT#{hash}").new rescue nil
|
44
|
+
end
|
45
|
+
# TODO: store jit settings in here instead of $RB_* variables
|
46
|
+
attr_accessor :file_name, :raw_code, :jit_settings
|
47
|
+
def initialize(file_name, jit_settings=1, outfile=nil, cache_dir=nil,validate = true, opts = nil)
|
48
|
+
@file_name = file_name
|
49
|
+
@no_write = (opts && opts[:no_write]) || false
|
50
|
+
if @file_name.start_with? "file:"
|
51
|
+
@file_name = @file_name.gsub(/^file\:/, '')
|
52
|
+
elsif @file_name.start_with? "jar:"
|
53
|
+
@no_write = true
|
54
|
+
elsif @file_name.start_with? "compoundjar:"
|
55
|
+
@no_write = true
|
56
|
+
end
|
57
|
+
@jit_settings = jit_settings
|
58
|
+
@run_count = 0
|
59
|
+
@opts = opts
|
60
|
+
@outfile = if @outfile
|
61
|
+
outfile
|
62
|
+
else
|
63
|
+
cache_dir = cache_dir || File.join(File.dirname(@file_name), ".jrubyfx_cache")
|
64
|
+
FileUtils.mkpath(cache_dir) unless File.directory?(cache_dir) or @no_write
|
65
|
+
@f_hash = Digest::SHA1.hexdigest(File.basename @file_name)
|
66
|
+
File.join(cache_dir, "#{@f_hash}.rb")
|
67
|
+
end
|
68
|
+
if File.exist?(@outfile) && !(opts && opts[:force])
|
69
|
+
@compiled = self.class.load_aot(@file_name, @outfile, validate)
|
70
|
+
if @compiled
|
71
|
+
dputs "got #{file_name} from cache"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
def hash
|
76
|
+
FxmlJitInfo.hash(@file_name)
|
77
|
+
end
|
78
|
+
def should_jit?
|
79
|
+
return false if @jit_settings == :no_jit || compiled?
|
80
|
+
return true if (@run_count += 1) >= @jit_settings
|
81
|
+
end
|
82
|
+
def compiled?
|
83
|
+
!!@compiled
|
84
|
+
end
|
85
|
+
def decompile
|
86
|
+
@compiled = nil
|
87
|
+
end
|
88
|
+
def __build_via_jit(__local_fxml_controller, __local_namespace, __local_jruby_ext)
|
89
|
+
@compiled.__build_via_jit(__local_fxml_controller, __local_namespace, __local_jruby_ext)
|
90
|
+
end
|
91
|
+
def compile(code=@raw_code)
|
92
|
+
@raw_code = code
|
93
|
+
# TODO: begin rescue end
|
94
|
+
full_code = <<METHOD_DEF
|
95
|
+
def __build_via_jit(__local_fxml_controller, __local_namespace, __local_jruby_ext)
|
96
|
+
__local_fx_id_setter = lambda do |name, __i|
|
97
|
+
__local_namespace[name] = __i
|
98
|
+
__local_fxml_controller.instance_variable_set(("@\#{name}").to_sym, __i)
|
99
|
+
end
|
100
|
+
#{code}
|
101
|
+
end
|
102
|
+
METHOD_DEF
|
103
|
+
;#)
|
104
|
+
unless @no_write
|
105
|
+
begin
|
106
|
+
jit_aot_cache(full_code)
|
107
|
+
rescue
|
108
|
+
p $!
|
109
|
+
jit_no_cache(full_code)
|
110
|
+
end
|
111
|
+
else
|
112
|
+
jit_no_cache(full_code)
|
113
|
+
end
|
114
|
+
if @opts && @opts[:compiled_hook]
|
115
|
+
@opts[:compiled_hook].call(@outfile)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
def jit_no_cache(full_code)
|
121
|
+
dputs "JIT only, no aot for #{@file_name}"
|
122
|
+
self.instance_eval full_code
|
123
|
+
@compiled = true
|
124
|
+
end
|
125
|
+
|
126
|
+
def jit_aot_cache(full_code)
|
127
|
+
File.open(@outfile, "w") do |f|
|
128
|
+
hash = hash()
|
129
|
+
f << <<AOT
|
130
|
+
# #{hash} encoding: utf-8
|
131
|
+
# @@ 1
|
132
|
+
|
133
|
+
########################### DO NOT MODIFY THIS FILE ###########################
|
134
|
+
# This file was automatically generated by JRubyFX-fxmlloader on #
|
135
|
+
# #{Time.now} for #{@file_name}
|
136
|
+
########################### DO NOT MODIFY THIS FILE ###########################
|
137
|
+
|
138
|
+
module JRubyFX
|
139
|
+
module GeneratedAssets
|
140
|
+
class AOT#{@f_hash}
|
141
|
+
include JRubyFX
|
142
|
+
#{full_code}
|
143
|
+
def hash
|
144
|
+
#{hash.inspect}
|
145
|
+
end
|
146
|
+
def compiled?
|
147
|
+
true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
AOT
|
153
|
+
end
|
154
|
+
puts "saved #{@outfile} to cache"
|
155
|
+
require @outfile
|
156
|
+
@compiled = JRubyFX::GeneratedAssets.const_get("AOT#{@f_hash}").new rescue nil
|
157
|
+
end
|
158
|
+
end
|