ruboto-core 0.1.0 → 0.2.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.
@@ -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
  }