ruboto-core 0.1.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,20 +1,20 @@
1
1
  require 'ruboto'
2
2
 
3
- ruboto_import_widgets :TextView, :LinearLayout, :Button
3
+ ruboto_import_widgets :Button, :LinearLayout, :TextView
4
4
 
5
5
  $activity.handle_create do |bundle|
6
6
  setTitle 'This is the Title'
7
7
 
8
8
  setup_content do
9
9
  linear_layout :orientation => LinearLayout::VERTICAL do
10
- @text_view = text_view :text => "What hath Matz wrought?", :id => 42
11
- button :text => "M-x butterfly", :width => :wrap_content, :id => 43
10
+ @text_view = text_view :text => 'What hath Matz wrought?', :id => 42
11
+ button :text => 'M-x butterfly', :width => :wrap_content, :id => 43
12
12
  end
13
13
  end
14
14
 
15
15
  handle_click do |view|
16
16
  if view.getText == 'M-x butterfly'
17
- @text_view.setText "What hath Matz wrought!"
17
+ @text_view.setText 'What hath Matz wrought!'
18
18
  toast 'Flipped a bit via butterfly'
19
19
  end
20
20
  end
@@ -2,11 +2,13 @@ package THE_PACKAGE;
2
2
 
3
3
  public class InheritingActivity extends org.ruboto.RubotoActivity {
4
4
  public void onCreate(android.os.Bundle arg0) {
5
- try {
6
- setSplash(Class.forName("THE_PACKAGE.R$layout").getField("splash").getInt(null));
7
- } catch (Exception e) {}
5
+ try {
6
+ setSplash(Class.forName("THE_PACKAGE.R$layout").getField("splash")
7
+ .getInt(null));
8
+ } catch (Exception e) {
9
+ }
8
10
 
9
- setScriptName("start.rb");
10
- super.onCreate(arg0);
11
- }
11
+ setScriptName("start.rb");
12
+ super.onCreate(arg0);
13
+ }
12
14
  }
@@ -1,10 +1,10 @@
1
1
  package THE_PACKAGE;
2
2
 
3
3
  public class InheritingBroadcastReceiver extends org.ruboto.RubotoBroadcastReceiver {
4
- public void onReceive(android.content.Context arg0, android.content.Intent arg1) {
5
-
6
- setScriptName("start.rb");
7
- super.onReceive(arg0,arg1);
8
- }
4
+ public void onReceive(android.content.Context arg0,
5
+ android.content.Intent arg1) {
6
+ setScriptName("start.rb");
7
+ super.onReceive(arg0, arg1);
8
+ }
9
9
 
10
10
  }
@@ -1,6 +1,6 @@
1
1
  package THE_PACKAGE;
2
2
 
3
- import org.jruby.Ruby;
3
+ import org.jruby.embed.ScriptingContainer;
4
4
  import org.jruby.javasupport.util.RuntimeHelpers;
5
5
  import org.jruby.runtime.builtin.IRubyObject;
6
6
  import org.jruby.javasupport.JavaUtil;
@@ -8,14 +8,14 @@ import org.jruby.exceptions.RaiseException;
8
8
  import org.ruboto.Script;
9
9
 
10
10
  public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
11
- private Ruby __ruby__;
11
+ private ScriptingContainer __ruby__;
12
12
 
13
13
  THE_CONSTANTS
14
14
  private IRubyObject[] callbackProcs = new IRubyObject[CONSTANTS_COUNT];
15
15
 
16
16
  THE_CONSTRUCTORS
17
17
 
18
- private Ruby getRuby() {
18
+ private ScriptingContainer getRuby() {
19
19
  if (__ruby__ == null) __ruby__ = Script.getRuby();
20
20
  return __ruby__;
21
21
  }
@@ -2,9 +2,8 @@ package THE_PACKAGE;
2
2
 
3
3
  public class InheritingService extends org.ruboto.RubotoService {
4
4
  public void onCreate() {
5
-
6
- setScriptName("start.rb");
7
- super.onCreate();
8
- }
5
+ setScriptName("start.rb");
6
+ super.onCreate();
7
+ }
9
8
 
10
9
  }
@@ -1,18 +1,23 @@
1
1
  package THE_PACKAGE;
2
2
 
3
+ import java.io.IOException;
4
+
3
5
  import org.jruby.Ruby;
6
+ import org.jruby.embed.ScriptingContainer;
7
+ import org.jruby.exceptions.RaiseException;
8
+ import org.jruby.javasupport.JavaUtil;
4
9
  import org.jruby.javasupport.util.RuntimeHelpers;
5
10
  import org.jruby.runtime.builtin.IRubyObject;
6
- import org.jruby.javasupport.JavaUtil;
7
- import org.jruby.exceptions.RaiseException;
8
11
  import org.ruboto.Script;
9
- import java.io.IOException;
12
+
10
13
  import android.app.ProgressDialog;
11
14
  import android.os.Handler;
12
15
 
13
16
  public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
14
- private Ruby __ruby__;
17
+ private ScriptingContainer __ruby__;
15
18
  private String scriptName;
19
+ private String rubyClassName;
20
+ private Object rubyInstance;
16
21
  private int splash = 0;
17
22
  private String remoteVariable = "";
18
23
  public Object[] args;
@@ -21,12 +26,14 @@ public class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
21
26
  THE_CONSTANTS
22
27
  private IRubyObject[] callbackProcs = new IRubyObject[CONSTANTS_COUNT];
23
28
 
24
- private Ruby getRuby() {
25
- if (__ruby__ == null) __ruby__ = Script.getRuby();
26
-
29
+ private ScriptingContainer getRuby() {
27
30
  if (__ruby__ == null) {
28
- Script.setUpJRuby(null);
29
- __ruby__ = Script.getRuby();
31
+ __ruby__ = Script.getRuby();
32
+
33
+ if (__ruby__ == null) {
34
+ Script.setUpJRuby(this);
35
+ __ruby__ = Script.getRuby();
36
+ }
30
37
  }
31
38
 
32
39
  return __ruby__;
@@ -59,6 +66,12 @@ THE_CONSTANTS
59
66
  args = new Object[1];
60
67
  args[0] = arg0;
61
68
 
69
+ android.os.Bundle configBundle = getIntent().getBundleExtra("RubotoActivity Config");
70
+
71
+ if (configBundle != null && configBundle.containsKey("Theme")) {
72
+ setTheme(configBundle.getInt("Theme"));
73
+ }
74
+
62
75
  super.onCreate(arg0);
63
76
 
64
77
  if (Script.getRuby() != null) {
@@ -79,7 +92,6 @@ THE_CONSTANTS
79
92
 
80
93
  private final Thread loadingThread = new Thread() {
81
94
  public void run(){
82
- Script.setUpJRuby(null);
83
95
  backgroundCreate();
84
96
  loadingHandler.post(loadingComplete);
85
97
  }
@@ -95,10 +107,8 @@ THE_CONSTANTS
95
107
  };
96
108
 
97
109
  private void backgroundCreate() {
98
- Script.copyScriptsIfNeeded(getFilesDir().getAbsolutePath() + "/scripts", getAssets());
99
- getRuby();
100
- Script.defineGlobalVariable("$activity", this);
101
- Script.defineGlobalVariable("$bundle", args[0]);
110
+ getRuby().put("$activity", this);
111
+ getRuby().put("$bundle", args[0]);
102
112
  }
103
113
 
104
114
  private void finishCreate() {
@@ -116,7 +126,12 @@ THE_CONSTANTS
116
126
  Script.execute(remoteVariable + "on_create($bundle)");
117
127
  } else {
118
128
  try {
119
- new Script(scriptName).execute();
129
+ new Script(scriptName).execute();
130
+ rubyClassName = this.getClass().getSimpleName();
131
+ if (getRuby().get(rubyClassName) != null) {
132
+ rubyInstance = Script.exec(rubyClassName + ".new");
133
+ getRuby().callMethod(rubyInstance, "on_create", configBundle);
134
+ }
120
135
  } catch(IOException e){
121
136
  e.printStackTrace();
122
137
  ProgressDialog.show(this, "Script failed", "Something bad happened", true, true);
@@ -1,16 +1,12 @@
1
1
  package THE_PACKAGE;
2
2
 
3
- import org.jruby.Ruby;
4
- import org.jruby.javasupport.util.RuntimeHelpers;
5
- import org.jruby.runtime.builtin.IRubyObject;
6
- import org.jruby.javasupport.JavaUtil;
7
- import org.jruby.exceptions.RaiseException;
8
- import org.ruboto.Script;
9
3
  import java.io.IOException;
10
- import android.app.ProgressDialog;
4
+
5
+ import org.jruby.embed.ScriptingContainer;
6
+ import org.jruby.runtime.builtin.IRubyObject;
11
7
 
12
8
  public abstract class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
13
- private Ruby __ruby__;
9
+ private ScriptingContainer __ruby__;
14
10
  private String scriptName;
15
11
  private String remoteVariable = "";
16
12
  public Object[] args;
@@ -18,12 +14,9 @@ public abstract class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
18
14
  THE_CONSTANTS
19
15
  private IRubyObject[] callbackProcs = new IRubyObject[CONSTANTS_COUNT];
20
16
 
21
- private Ruby getRuby() {
22
- if (__ruby__ == null) __ruby__ = Script.getRuby();
23
-
17
+ private ScriptingContainer getRuby() {
24
18
  if (__ruby__ == null) {
25
- Script.setUpJRuby(null);
26
- __ruby__ = Script.getRuby();
19
+ __ruby__ = Script.getRuby();
27
20
  }
28
21
 
29
22
  return __ruby__;
@@ -4,13 +4,14 @@ import org.jruby.Ruby;
4
4
  import org.jruby.javasupport.util.RuntimeHelpers;
5
5
  import org.jruby.runtime.builtin.IRubyObject;
6
6
  import org.jruby.javasupport.JavaUtil;
7
+ import org.jruby.embed.ScriptingContainer;
7
8
  import org.jruby.exceptions.RaiseException;
8
9
  import org.ruboto.Script;
9
10
  import java.io.IOException;
10
11
  import android.app.ProgressDialog;
11
12
 
12
13
  public abstract class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
13
- private Ruby __ruby__;
14
+ private ScriptingContainer __ruby__;
14
15
  private String scriptName;
15
16
  private String remoteVariable = "";
16
17
  public Object[] args;
@@ -18,11 +19,11 @@ public abstract class THE_RUBOTO_CLASS THE_ACTION THE_ANDROID_CLASS {
18
19
  THE_CONSTANTS
19
20
  private IRubyObject[] callbackProcs = new IRubyObject[CONSTANTS_COUNT];
20
21
 
21
- private Ruby getRuby() {
22
+ private ScriptingContainer getRuby() {
22
23
  if (__ruby__ == null) __ruby__ = Script.getRuby();
23
24
 
24
25
  if (__ruby__ == null) {
25
- Script.setUpJRuby(null);
26
+ Script.setUpJRuby(this);
26
27
  __ruby__ = Script.getRuby();
27
28
  }
28
29
 
@@ -1,53 +1,43 @@
1
1
  package org.ruboto;
2
2
 
3
- import java.io.BufferedReader;
4
- import java.io.BufferedWriter;
3
+ import android.content.Context;
4
+ import android.content.pm.ApplicationInfo;
5
+ import android.content.pm.PackageInfo;
6
+ import android.content.pm.PackageManager;
7
+ import android.content.pm.PackageManager.NameNotFoundException;
8
+ import android.content.res.AssetManager;
9
+ import android.os.Environment;
10
+ import android.util.Log;
11
+
5
12
  import java.io.BufferedOutputStream;
13
+ import java.io.BufferedReader;
6
14
  import java.io.File;
15
+ import java.io.FileOutputStream;
7
16
  import java.io.FileReader;
8
- import java.io.FileWriter;
9
17
  import java.io.FilenameFilter;
10
- import java.io.FileOutputStream;
11
18
  import java.io.IOException;
12
- import java.io.PrintStream;
13
19
  import java.io.InputStream;
14
20
  import java.io.OutputStream;
15
- import java.util.ArrayList;
16
- import java.util.Arrays;
17
- import java.util.List;
21
+ import java.io.PrintStream;
18
22
 
19
- import org.jruby.Ruby;
20
23
  import org.jruby.RubyInstanceConfig;
24
+ import org.jruby.embed.ScriptingContainer;
21
25
  import org.jruby.exceptions.RaiseException;
22
- import org.jruby.javasupport.JavaUtil;
23
- import org.jruby.parser.EvalStaticScope;
24
- import org.jruby.runtime.builtin.IRubyObject;
25
- import org.jruby.runtime.DynamicScope;
26
- import org.jruby.runtime.ThreadContext;
27
- import org.jruby.runtime.scope.ManyVarsDynamicScope;
28
-
29
- import android.os.Environment;
30
- import android.util.Log;
31
- import android.content.res.AssetManager;
32
- import org.apache.http.client.methods.HttpGet;
33
- import org.apache.http.impl.client.BasicResponseHandler;
34
- import org.apache.http.impl.client.DefaultHttpClient;
35
26
 
36
27
  public class Script {
37
28
  private static String scriptsDir = "scripts";
38
29
  private static File scriptsDirFile = null;
39
-
30
+
40
31
  private String name = null;
41
- private static Ruby ruby;
42
- private static DynamicScope scope;
32
+ private static ScriptingContainer ruby;
43
33
  private static boolean initialized = false;
44
34
 
45
35
  private String contents = null;
46
36
 
47
- public static final String TAG = "RUBOTO"; //for logging
37
+ public static final String TAG = "RUBOTO"; // for logging
48
38
 
49
39
  /*************************************************************************************************
50
- *
40
+ *
51
41
  * Static Methods: JRuby Execution
52
42
  */
53
43
 
@@ -61,56 +51,66 @@ public class Script {
61
51
  return initialized;
62
52
  }
63
53
 
64
- public static synchronized Ruby setUpJRuby(PrintStream out) {
54
+ public static synchronized ScriptingContainer setUpJRuby(Context appContext) {
55
+ return setUpJRuby(appContext, System.out);
56
+ }
57
+
58
+ public static synchronized ScriptingContainer setUpJRuby(Context appContext, PrintStream out) {
65
59
  if (ruby == null) {
66
- System.setProperty("jruby.interfaces.useProxy", "true");
67
- RubyInstanceConfig config = new RubyInstanceConfig();
60
+ Log.d(TAG, "Setting up JRuby runtime");
61
+ System.setProperty("jruby.interfaces.useProxy", "true");
62
+ System.setProperty("jruby.bytecode.version", "1.5");
63
+ // ruby = new ScriptingContainer(LocalContextScope.THREADSAFE);
64
+ ruby = new ScriptingContainer();
65
+ RubyInstanceConfig config = ruby.getProvider().getRubyInstanceConfig();
68
66
  config.setCompileMode(RubyInstanceConfig.CompileMode.OFF);
69
67
 
70
68
  config.setLoader(Script.class.getClassLoader());
71
- if (scriptsDir != null) config.setCurrentDirectory(scriptsDir);
72
-
69
+ if (scriptsDir != null) {
70
+ Log.d(TAG, "Setting JRuby current directory to " + scriptsDir);
71
+ config.setCurrentDirectory(scriptsDir);
72
+ }
73
73
  if (out != null) {
74
74
  config.setOutput(out);
75
75
  config.setError(out);
76
76
  }
77
-
78
- /* Set up Ruby environment */
79
- ruby = Ruby.newInstance(config);
80
-
81
- ThreadContext context = ruby.getCurrentContext();
82
- DynamicScope currentScope = context.getCurrentScope();
83
- scope = new ManyVarsDynamicScope(new EvalStaticScope(currentScope.getStaticScope()), currentScope);
84
-
77
+ copyScriptsIfNeeded(appContext);
85
78
  initialized = true;
86
- }
79
+ } else {
80
+ while (!initialized) {
81
+ Log.i(TAG, "Waiting for JRuby runtime to initialize.");
82
+ try {
83
+ Thread.sleep(1000);
84
+ } catch (InterruptedException iex) {
85
+ }
86
+ }
87
+ }
87
88
 
88
89
  return ruby;
89
90
  }
90
91
 
91
92
  public static String execute(String code) {
92
- if (!initialized) return null;
93
93
  try {
94
- return exec(code).inspect().asJavaString();
94
+ return getRuby().callMethod(exec(code), "inspect", String.class);
95
95
  } catch (RaiseException re) {
96
- re.printStackTrace(ruby.getErrorStream());
96
+ re.printStackTrace(ruby.getError());
97
97
  return null;
98
98
  }
99
99
  }
100
100
 
101
- public static IRubyObject exec(String code) throws RaiseException {
102
- return ruby.evalScriptlet(code, scope);
103
- }
101
+ public static Object exec(String code) throws RaiseException {
102
+ return ruby.runScriptlet(code);
103
+ }
104
104
 
105
105
  public static void defineGlobalConstant(String name, Object object) {
106
- ruby.defineGlobalConstant(name, JavaUtil.convertJavaToRuby(ruby, object));
106
+ ruby.put(name, object);
107
107
  }
108
108
 
109
109
  public static void defineGlobalVariable(String name, Object object) {
110
- ruby.getGlobalVariables().set(name, JavaUtil.convertJavaToRuby(ruby, object));
110
+ ruby.put(name, object);
111
111
  }
112
112
 
113
- public static Ruby getRuby() {
113
+ public static ScriptingContainer getRuby() {
114
114
  return ruby;
115
115
  }
116
116
 
@@ -122,8 +122,11 @@ public class Script {
122
122
  public static void setDir(String dir) {
123
123
  scriptsDir = dir;
124
124
  scriptsDirFile = new File(dir);
125
- if (ruby != null) ruby.setCurrentDirectory(scriptsDir);
126
- }
125
+ if (ruby != null) {
126
+ Log.d(TAG, "Changing JRuby current directory to " + scriptsDir);
127
+ ruby.setCurrentDirectory(scriptsDir);
128
+ }
129
+ }
127
130
 
128
131
  public static String getDir() {
129
132
  return scriptsDir;
@@ -135,11 +138,19 @@ public class Script {
135
138
 
136
139
  public static Boolean configDir(String noSdcard) {
137
140
  setDir(noSdcard);
141
+ if (!ruby.getLoadPaths().contains(noSdcard)) {
142
+ Log.i(TAG, "Adding scripts dir to load path: " + noSdcard);
143
+ java.util.List paths = ruby.getLoadPaths();
144
+ paths.add(noSdcard);
145
+ ruby.setLoadPaths(paths);
146
+ }
138
147
 
139
148
  /* Create directory if it doesn't exist */
140
149
  if (!scriptsDirFile.exists()) {
141
- // TODO check return code
142
- scriptsDirFile.mkdir();
150
+ boolean dirCreatedOk = scriptsDirFile.mkdirs();
151
+ if (!dirCreatedOk) {
152
+ throw new RuntimeException("Unable to create script directory");
153
+ }
143
154
  return true;
144
155
  }
145
156
 
@@ -178,10 +189,56 @@ public class Script {
178
189
  }
179
190
  }
180
191
 
181
- public static void copyScriptsIfNeeded(String to, AssetManager assets) {
192
+ public static void copyAssets(Context context, String directory) {
193
+ File dest = new File(scriptsDirFile.getParentFile(), directory);
194
+ if (dest.exists() || dest.mkdir()) {
195
+ copyScripts(directory, dest, context.getAssets());
196
+ } else {
197
+ throw new RuntimeException("Unable to create scripts directory: " + dest);
198
+ }
199
+ }
200
+
201
+ private static boolean isDebugBuild(Context context) {
202
+ PackageManager pm = context.getPackageManager();
203
+ PackageInfo pi;
204
+ try {
205
+ pi = pm.getPackageInfo(context.getPackageName(), 0);
206
+ return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
207
+ } catch (NameNotFoundException e) {
208
+ return false;
209
+ }
210
+
211
+ }
212
+
213
+ private static void copyScriptsIfNeeded(Context context) {
214
+ File toFile = null;
215
+ if (isDebugBuild(context)) {
216
+
217
+ // FIXME(uwe): Simplify this as soon as we drop support for android-7 or JRuby 1.5.6 or JRuby 1.6.2
218
+ Log.i(TAG, "JRuby VERSION: " + org.jruby.runtime.Constants.VERSION);
219
+ if (!org.jruby.runtime.Constants.VERSION.equals("1.5.6") && !org.jruby.runtime.Constants.VERSION.equals("1.6.2") && android.os.Build.VERSION.SDK_INT >= 8) {
220
+ ruby.put("script_context", context);
221
+ toFile = (File) exec("script_context.getExternalFilesDir(nil)");
222
+ } else {
223
+ toFile = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/files");
224
+ Log.e(TAG, "Calculated path to sdcard the old way: " + toFile);
225
+ }
226
+ // FIXME end
227
+
228
+ if (toFile == null || (!toFile.exists() && !toFile.mkdirs())) {
229
+ Log.e(TAG,
230
+ "Development mode active, but sdcard is not available. Make sure you have added\n<uses-permission android:name='android.permission.WRITE_EXTERNAL_STORAGE' />\nto your AndroidManifest.xml file.");
231
+ toFile = context.getFilesDir();
232
+ }
233
+ } else {
234
+ toFile = context.getFilesDir();
235
+ }
236
+ String to = toFile.getAbsolutePath() + "/scripts";
237
+ Log.i(TAG, "Checking scripts in " + to);
182
238
  /* the if makes sure we only do this the first time */
183
239
  if (configDir(to)) {
184
- copyScripts("scripts", scriptsDirFile, assets);
240
+ Log.i(TAG, "Copying scripts to " + to);
241
+ copyAssets(context, "scripts");
185
242
  }
186
243
  }
187
244
 
@@ -198,7 +255,6 @@ public class Script {
198
255
  public Script(String name, String contents) {
199
256
  this.name = name;
200
257
  this.contents = contents;
201
- File file = getFile();
202
258
  }
203
259
 
204
260
  /*************************************************************************************************
@@ -225,7 +281,9 @@ public class Script {
225
281
  StringBuilder source = new StringBuilder();
226
282
  while (true) {
227
283
  String line = buffer.readLine();
228
- if (line == null) break;
284
+ if (line == null) {
285
+ break;
286
+ }
229
287
  source.append(line).append("\n");
230
288
  }
231
289
  buffer.close();
@@ -239,6 +297,7 @@ public class Script {
239
297
  */
240
298
 
241
299
  public String execute() throws IOException {
300
+ Script.getRuby().setScriptFilename(name);
242
301
  return Script.execute(getContents());
243
302
  }
244
303
  }