cappruby 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/bin/cappruby +24 -0
- data/build/CappRuby/CappRuby.j +1 -0
- data/cappruby.gemspec +67 -0
- data/demos/simple_app/config/build.yml +0 -0
- data/demos/simple_app/lib/application.rb +29 -0
- data/demos/simple_app/lib/menu.rb +18 -0
- data/framework/array.js +46 -0
- data/framework/cappruby.js +52 -0
- data/framework/class.js +127 -0
- data/framework/enumerator.js +39 -0
- data/framework/file.js +42 -0
- data/framework/geometry.js +106 -0
- data/framework/hash.js +109 -0
- data/framework/mapings.js +86 -0
- data/framework/method.js +120 -0
- data/framework/module.js +72 -0
- data/framework/object.js +128 -0
- data/framework/objj_additions.js +84 -0
- data/framework/proc.js +31 -0
- data/framework/string.js +101 -0
- data/framework/variable.js +53 -0
- data/framework/vm.js +176 -0
- data/framework/window.js +68 -0
- data/lib/cappruby/app_builder.rb +135 -0
- data/lib/cappruby/framework_builder.rb +60 -0
- data/lib/cappruby/ruby_builder.rb +494 -0
- data/lib/cappruby.rb +73 -0
- metadata +92 -0
data/framework/string.js
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
/*
|
2
|
+
* string.js
|
3
|
+
* cappruby
|
4
|
+
*
|
5
|
+
* Created by Adam Beynon.
|
6
|
+
* Copyright 2010 Adam Beynon.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
|
27
|
+
rb_cString = nil;
|
28
|
+
rb_cSymbol = nil;
|
29
|
+
|
30
|
+
// hash of symbol names to actual sym values. Like ruby, only one object per
|
31
|
+
// symbol is created. use ID2SYM to get instance, or make one.
|
32
|
+
rb_sym_stack = { };
|
33
|
+
|
34
|
+
function ID2SYM(id) {
|
35
|
+
var s = rb_sym_stack[id];
|
36
|
+
if (!s) {
|
37
|
+
s = cr_send(rb_cSymbol, "alloc", [id], nil, 0);
|
38
|
+
s.ptr = id;
|
39
|
+
rb_sym_stack[id] = s;
|
40
|
+
}
|
41
|
+
return s;
|
42
|
+
};
|
43
|
+
|
44
|
+
function SYM2ID(sym) {
|
45
|
+
return sym.ptr;
|
46
|
+
};
|
47
|
+
|
48
|
+
function rb_sym_to_s(sym, sel) {
|
49
|
+
return sym.ptr;
|
50
|
+
};
|
51
|
+
|
52
|
+
function rb_sym_to_sym(sym, sel) {
|
53
|
+
return sym;
|
54
|
+
};
|
55
|
+
|
56
|
+
function rb_sym_to_proc(sym, sel) {
|
57
|
+
throw "sym#to_proc not uet implemented"
|
58
|
+
};
|
59
|
+
|
60
|
+
function rb_str_to_s(str, sel) {
|
61
|
+
return new String(str);
|
62
|
+
};
|
63
|
+
|
64
|
+
function Init_String() {
|
65
|
+
// string
|
66
|
+
rb_cString = objj_getClass("CPString");
|
67
|
+
// rb_include_module(rb_cString, rb_mComparable);
|
68
|
+
|
69
|
+
rb_define_method(rb_cString, "to_s", rb_str_to_s, 0);
|
70
|
+
|
71
|
+
// symbol
|
72
|
+
rb_cSymbol = rb_define_class("Symbol", rb_cObject);
|
73
|
+
|
74
|
+
// rb_define_method(rb_cSymbol, "==", rb_sym_equal, 1);
|
75
|
+
// rb_define_method(rb_cSymbol, "inspect", rb_sym_inspect, 0);
|
76
|
+
rb_define_method(rb_cSymbol, "to_s", rb_sym_to_s, 0);
|
77
|
+
rb_define_method(rb_cSymbol, "id2name", rb_sym_to_s, 0);
|
78
|
+
rb_define_method(rb_cSymbol, "intern", rb_sym_to_sym, 0);
|
79
|
+
rb_define_method(rb_cSymbol, "to_sym", rb_sym_to_sym, 0);
|
80
|
+
rb_define_method(rb_cSymbol, "to_proc", rb_sym_to_proc, 0);
|
81
|
+
// rb_define_method(rb_cSymbol, "succ", rb_sym_succ, 0);
|
82
|
+
// rb_define_method(rb_cSymbol, "next", rb_sym_succ, 0);
|
83
|
+
//
|
84
|
+
// rb_define_method(rb_cSymbol, "<=>", rb_sym_cmp, 1);
|
85
|
+
// rb_define_method(rb_cSymbol, "casecmp", rb_sym_casecmp, 1);
|
86
|
+
// rb_define_method(rb_cSymbol, "=~", rb_sym_match, 1);
|
87
|
+
//
|
88
|
+
// rb_define_method(rb_cSymbol, "[]", rb_sym_aref, -1);
|
89
|
+
// rb_define_method(rb_cSymbol, "slice", rb_sym_aref, -1);
|
90
|
+
// rb_define_method(rb_cSymbol, "length", rb_sym_length, 0);
|
91
|
+
// rb_define_method(rb_cSymbol, "size", rb_sym_length, 0);
|
92
|
+
// rb_define_method(rb_cSymbol, "empty?", rb_sym_empty, 0);
|
93
|
+
// rb_define_method(rb_cSymbol, "match", rb_sym_match, 1);
|
94
|
+
//
|
95
|
+
// rb_define_method(rb_cSymbol, "upcase", rb_sym_upcase, 0);
|
96
|
+
// rb_define_method(rb_cSymbol, "downcase", rb_sym_downcase, 0);
|
97
|
+
// rb_define_method(rb_cSymbol, "capitalize", rb_sym_capitalize, 0);
|
98
|
+
// rb_define_method(rb_cSymbol, "swapcase", rb_sym_swapcase, 0);
|
99
|
+
//
|
100
|
+
// rb_define_method(rb_cSymbol, "encoding", rb_sym_encoding, 0);
|
101
|
+
};
|
@@ -0,0 +1,53 @@
|
|
1
|
+
/*
|
2
|
+
* variable.js
|
3
|
+
* cappruby
|
4
|
+
*
|
5
|
+
* Created by Adam Beynon.
|
6
|
+
* Copyright 2010 Adam Beynon.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
|
27
|
+
function rb_const_set(klass, id, val) {
|
28
|
+
klass[id] = val;
|
29
|
+
};
|
30
|
+
|
31
|
+
function rb_const_defined(klass, id) {
|
32
|
+
while (klass) {
|
33
|
+
if (klass[id] !== undefined) return true;
|
34
|
+
klass = klass.super_class;
|
35
|
+
}
|
36
|
+
// try window scope..
|
37
|
+
if (window[id] !== undefined) return true;
|
38
|
+
return false;
|
39
|
+
};
|
40
|
+
|
41
|
+
function rb_const_get(klass, id) {
|
42
|
+
while (klass) {
|
43
|
+
if (klass[id] !== undefined) return klass[id];
|
44
|
+
klass = klass.super_class;
|
45
|
+
}
|
46
|
+
// try window scope..
|
47
|
+
if (window[id] !== undefined) {
|
48
|
+
// if we find it, pop it into the rb_cObject scope
|
49
|
+
rb_const_set(rb_cObject, id, window[id]);
|
50
|
+
return window[id];
|
51
|
+
}
|
52
|
+
throw "cannot find constant " + id;
|
53
|
+
};
|
data/framework/vm.js
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
/*
|
2
|
+
* vm.js
|
3
|
+
* cappruby
|
4
|
+
*
|
5
|
+
* Created by Adam Beynon.
|
6
|
+
* Copyright 2010 Adam Beynon.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
|
27
|
+
/**
|
28
|
+
This isnt actually a vm. All the functions in here are what are called in the
|
29
|
+
output in the compiled ruby. They are more efficient and handle the delecate
|
30
|
+
nature of the ruby commands. They adjust the value of self etc to be the right
|
31
|
+
object for the right context;
|
32
|
+
|
33
|
+
Every method is prepended with cr_ - cappruby.
|
34
|
+
*/
|
35
|
+
|
36
|
+
/**
|
37
|
+
Global block. Used for passing blocks around functions. We need this as we
|
38
|
+
are not using a stack based runtime. :(
|
39
|
+
*/
|
40
|
+
cappruby_block = nil;
|
41
|
+
|
42
|
+
/**
|
43
|
+
top self context in ruby. All files will be executed with this top self value
|
44
|
+
as "self".
|
45
|
+
*/
|
46
|
+
cappruby_top_self = nil;
|
47
|
+
|
48
|
+
/**
|
49
|
+
Initialize vm
|
50
|
+
*/
|
51
|
+
function Init_VM() {
|
52
|
+
cappruby_top_self = class_createInstance(rb_cObject);
|
53
|
+
};
|
54
|
+
|
55
|
+
/**
|
56
|
+
defineclass
|
57
|
+
|
58
|
+
FIXME: this should really include arity as well.. number or array for complex
|
59
|
+
*/
|
60
|
+
cr_a = function cr_defineclass(base, super_class, name, body, flag) {
|
61
|
+
var klass;
|
62
|
+
switch (flag) {
|
63
|
+
case 0:
|
64
|
+
if (super_class == nil) super_class = CPObject;
|
65
|
+
klass = rb_define_class(name, super_class);
|
66
|
+
body(klass);
|
67
|
+
break;
|
68
|
+
default:
|
69
|
+
throw "unknwon defineclass type"
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
/**
|
74
|
+
definemethod
|
75
|
+
*/
|
76
|
+
cr_b = function cr_definemethod(base, id, body, is_singleton) {
|
77
|
+
// var m = new cappruby_method_t(id, body, []);
|
78
|
+
// arity? hmm, maybe..
|
79
|
+
if (is_singleton) {
|
80
|
+
throw "cr_b: singleton method not uet implemented"
|
81
|
+
}
|
82
|
+
else {
|
83
|
+
// arity?
|
84
|
+
rb_define_method(base, id, body, -1);
|
85
|
+
// base.method_list.push(m);
|
86
|
+
// base.method_dtable[id] = m;
|
87
|
+
// m.method_imp.displayName = base.name + "#" + id;
|
88
|
+
}
|
89
|
+
};
|
90
|
+
|
91
|
+
/**
|
92
|
+
send
|
93
|
+
|
94
|
+
op_flag can be used to detect private calls etc
|
95
|
+
*/
|
96
|
+
cr_b = function cr_send(recv, id, argv, blockiseq, op_flag) {
|
97
|
+
var imp, klass;
|
98
|
+
|
99
|
+
// make sure we have a reciever and a class. JSON objects, Rects etc will not
|
100
|
+
// have a ".isa" property. In which case, find one for it.
|
101
|
+
if (recv === nil || recv === undefined) {
|
102
|
+
klass = rb_cNilClass;
|
103
|
+
}
|
104
|
+
else if (!recv.isa) {
|
105
|
+
klass = rb_find_class_for_obj(recv);
|
106
|
+
}
|
107
|
+
else {
|
108
|
+
klass = recv.isa;
|
109
|
+
}
|
110
|
+
|
111
|
+
imp = rb_search_method(klass, id);
|
112
|
+
// if we could not find it, try it with/without a colon on the end
|
113
|
+
if (!imp) {
|
114
|
+
if (id[id.length -1] == ":") {
|
115
|
+
// already has a colon.. so remove it and try
|
116
|
+
}
|
117
|
+
else {
|
118
|
+
// doesnt have a colon, so add one and try..
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
if (!imp) {
|
123
|
+
throw "method missing: " + id
|
124
|
+
}
|
125
|
+
|
126
|
+
// setup block - might be undefined, nil or null..
|
127
|
+
if (blockiseq != nil) cappruby_block = blockiseq;
|
128
|
+
|
129
|
+
// do actual send message
|
130
|
+
switch (argv.length) {
|
131
|
+
case 0: return imp(recv, id);
|
132
|
+
case 1: return imp(recv, id, argv[0]);
|
133
|
+
case 2: return imp(recv, id, argv[0], argv[1]);
|
134
|
+
case 3: return imp(recv, id, argv[0], argv[1], argv[2]);
|
135
|
+
case 4: return imp(recv, id, argv[0], argv[1], argv[2], argv[3]);
|
136
|
+
case 5: return imp(recv, id, argv[0], argv[1], argv[2], argv[3], argv[4]);
|
137
|
+
default: throw "currently too many args: " + argv.length + " for " + id
|
138
|
+
}
|
139
|
+
};
|
140
|
+
|
141
|
+
/**
|
142
|
+
getconstant
|
143
|
+
*/
|
144
|
+
cr_c = function cr_getconstant(base, id) {
|
145
|
+
// if base is an object, then use its class (base.isa)
|
146
|
+
if (base.isa.info & CLS_CLASS) base = base.isa;
|
147
|
+
return rb_const_get(base, id);
|
148
|
+
};
|
149
|
+
|
150
|
+
/**
|
151
|
+
functioncall
|
152
|
+
*/
|
153
|
+
cr_d = function cr_functioncall(id, argv) {
|
154
|
+
throw "doing " + id
|
155
|
+
};
|
156
|
+
|
157
|
+
/**
|
158
|
+
newhash
|
159
|
+
*/
|
160
|
+
cr_e = function cr_newhash() {
|
161
|
+
return rb_hash_new.apply(rb_hash_new, arguments);
|
162
|
+
};
|
163
|
+
|
164
|
+
/**
|
165
|
+
yield a block
|
166
|
+
|
167
|
+
argv in array
|
168
|
+
|
169
|
+
need to wrap in a try block. return/break etc from block/yield is different
|
170
|
+
from a proc. if we are a proc, then we need to catch breaks/returns... this
|
171
|
+
might/should be done in proc#call ?
|
172
|
+
*/
|
173
|
+
cr_y = function cr_yield(block, argv) {
|
174
|
+
if (block == nil) throw "no block given..."
|
175
|
+
return block.apply(block, argv);
|
176
|
+
};
|
data/framework/window.js
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
/*
|
2
|
+
* window.js
|
3
|
+
* cappruby
|
4
|
+
*
|
5
|
+
* Created by Adam Beynon.
|
6
|
+
* Copyright 2010 Adam Beynon.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
* of this software and associated documentation files (the "Software"), to deal
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
13
|
+
* furnished to do so, subject to the following conditions:
|
14
|
+
*
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
16
|
+
* all copies or substantial portions of the Software.
|
17
|
+
*
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
* THE SOFTWARE.
|
25
|
+
*/
|
26
|
+
|
27
|
+
/**
|
28
|
+
window :title => "Adam", :frame => [100, 300] do |win|
|
29
|
+
...
|
30
|
+
end
|
31
|
+
|
32
|
+
Block is optional, and if given, the created window is passed. A set of
|
33
|
+
default options are used to "setup" the window in a default state.
|
34
|
+
*/
|
35
|
+
function cr_mappings_window(self, sel, options) {
|
36
|
+
var _$ = cappruby_block; cappruby_block = nil;
|
37
|
+
var h = cr_mappings_collate_options('window', options);
|
38
|
+
|
39
|
+
var win = objj_msgSend(objj_msgSend(CPWindow, "alloc"), "initWithContentRect:styleMask:", CGRectMake(100,100,400,300), CPTitledWindowMask);
|
40
|
+
|
41
|
+
objj_msgSend(win, "setTitle:", rb_hash_delete(h, 'delete:', ID2SYM("title")));
|
42
|
+
|
43
|
+
if(_$) { // if block given
|
44
|
+
cr_yield(_$, [win]);
|
45
|
+
}
|
46
|
+
|
47
|
+
objj_msgSend(win, "orderFront:", self);
|
48
|
+
|
49
|
+
return win;
|
50
|
+
};
|
51
|
+
|
52
|
+
/**
|
53
|
+
CPWindow#<<(subview)
|
54
|
+
CPWindow#addSubview(subview)
|
55
|
+
|
56
|
+
Add a subview to the windows' contentView.
|
57
|
+
*/
|
58
|
+
function cr_window_add_subview(win, sel, view) {
|
59
|
+
var content_view = objj_msgSend(win, "contentView");
|
60
|
+
objj_msgSend(content_view, "addSubview:", view);
|
61
|
+
return view;
|
62
|
+
};
|
63
|
+
|
64
|
+
function Init_Mappings_Window() {
|
65
|
+
rb_define_method(rb_mKernel, "window:", cr_mappings_window, 1);
|
66
|
+
rb_define_method(CPWindow, "<<", cr_window_add_subview, 1);
|
67
|
+
rb_define_method(CPWindow, "addSubview:", cr_window_add_subview, 1);
|
68
|
+
};
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#
|
2
|
+
# app_builder.rb
|
3
|
+
# cappruby
|
4
|
+
#
|
5
|
+
# Created by Adam Beynon.
|
6
|
+
# Copyright 2010 Adam Beynon.
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
16
|
+
# all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
# THE SOFTWARE.
|
25
|
+
#
|
26
|
+
|
27
|
+
module CappRuby
|
28
|
+
|
29
|
+
class AppBuilder
|
30
|
+
|
31
|
+
attr_reader :app_root, :app_name, :app_title, :build_options
|
32
|
+
|
33
|
+
def initialize(args)
|
34
|
+
@app_root = Dir.getwd
|
35
|
+
@app_name = File.basename(@app_root)
|
36
|
+
@app_title = (@app_name.split('_').collect { |p| p.capitalize }).join ' '
|
37
|
+
|
38
|
+
unless File.exist? 'config/build.yml'
|
39
|
+
puts "Missing config/build.yml file. Sure this is an application dir?"
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
@build_options = YAML.load_file('config/build.yml')
|
44
|
+
end
|
45
|
+
|
46
|
+
def build_dir
|
47
|
+
@build_dir ||= File.join(@app_root, 'build')
|
48
|
+
end
|
49
|
+
|
50
|
+
def build!
|
51
|
+
# also rebuild CappRuby framework (for now)
|
52
|
+
FrameworkBuilder.new.build!
|
53
|
+
FileUtils.mkdir_p build_dir
|
54
|
+
write_info_plist_file
|
55
|
+
write_main_j_file
|
56
|
+
write_index_html_file
|
57
|
+
|
58
|
+
File.symlink(File.join(@app_root, 'frameworks'), File.join(build_dir, 'Frameworks')) unless File.exist? File.join(build_dir, 'Frameworks')
|
59
|
+
end
|
60
|
+
|
61
|
+
def info_plist_file
|
62
|
+
File.join(build_dir, 'Info.plist')
|
63
|
+
end
|
64
|
+
|
65
|
+
def write_info_plist_file
|
66
|
+
File.open(info_plist_file, 'w') do |f|
|
67
|
+
f.puts %{<?xml version="1.0" encoding="UTF-8"?>}
|
68
|
+
f.puts %{<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">}
|
69
|
+
f.puts %{<plist version="1.0">}
|
70
|
+
f.puts %{<dict>}
|
71
|
+
f.puts %{ <key>CPApplicationDelegateClass</key>}
|
72
|
+
f.puts %{ <string>AppController</string>}
|
73
|
+
f.puts %{ <key>CPBundleName</key>}
|
74
|
+
f.puts %{ <string>#{app_name}</string>}
|
75
|
+
f.puts %{ <key>CPPrincipalClass</key>}
|
76
|
+
f.puts %{ <string>CPApplication</string>}
|
77
|
+
f.puts %{</dict>}
|
78
|
+
f.puts %{</plist>}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def main_j_file
|
83
|
+
File.join(build_dir, 'main.j')
|
84
|
+
end
|
85
|
+
|
86
|
+
def write_main_j_file
|
87
|
+
File.open(main_j_file, 'w') do |f|
|
88
|
+
f.puts %{@import <Foundation/Foundation.j>}
|
89
|
+
f.puts %{@import <AppKit/AppKit.j>}
|
90
|
+
f.puts %{@import <CappRuby/CappRuby.j>}
|
91
|
+
|
92
|
+
f.puts %{function main(args, namedArgs) \{}
|
93
|
+
f.puts %{cappruby_main("/lib/application.rb", args, namedArgs);}
|
94
|
+
f.puts %{\};}
|
95
|
+
|
96
|
+
# now we need to write all .rb files (in opal compatible way)
|
97
|
+
rb_sources = File.join(app_root, 'lib', '**', '*.rb')
|
98
|
+
Dir.glob(rb_sources).each do |rb|
|
99
|
+
name = /^#{app_root}(.*)$/.match(rb)[1]
|
100
|
+
b = RubyBuilder.new(rb, self, name)
|
101
|
+
c = b.build!
|
102
|
+
f.puts %{cappruby_file("#{name}", #{c});}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def index_html_file
|
108
|
+
File.join(build_dir, 'index.html')
|
109
|
+
end
|
110
|
+
|
111
|
+
def write_index_html_file
|
112
|
+
File.open(index_html_file, 'w') do |f|
|
113
|
+
f.puts %{<?xml version="1.0" encoding="UTF-8"?>}
|
114
|
+
f.puts %{<!DOCTYPE html
|
115
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
116
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">}
|
117
|
+
f.puts %{<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en">}
|
118
|
+
f.puts %{<head>}
|
119
|
+
f.puts %{<meta http-equiv="X-UA-Compatible" content="IE-EmulateIE7" />}
|
120
|
+
f.puts %{<title>#{app_title}</title>}
|
121
|
+
f.puts %{<script type="text/javascript">}
|
122
|
+
f.puts %{OBJJ_MAIN_FILE = "main.j"}
|
123
|
+
f.puts %{</script>}
|
124
|
+
f.puts %{<script src = "Frameworks/Objective-J/Objective-J.js" type = "text/javascript"></script>}
|
125
|
+
f.puts %{<style type = "text/css">}
|
126
|
+
f.puts %{body{margin:0; padding:0;}}
|
127
|
+
f.puts %{</style>}
|
128
|
+
f.puts %{</head>}
|
129
|
+
f.puts %{<body>}
|
130
|
+
f.puts %{</body>}
|
131
|
+
f.puts %{</html>}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#
|
2
|
+
# framework.rb
|
3
|
+
# cappruby
|
4
|
+
#
|
5
|
+
# Created by Adam Beynon.
|
6
|
+
# Copyright 2010 Adam Beynon.
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
16
|
+
# all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
# THE SOFTWARE.
|
25
|
+
#
|
26
|
+
|
27
|
+
module CappRuby
|
28
|
+
|
29
|
+
# class used for building CappRuby framework
|
30
|
+
class FrameworkBuilder
|
31
|
+
|
32
|
+
attr_reader :build_dir
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
@app_root = Dir.getwd
|
36
|
+
@build_dir = File.join(Dir.getwd, 'frameworks', 'CappRuby')
|
37
|
+
end
|
38
|
+
|
39
|
+
def build!
|
40
|
+
FileUtils.mkdir_p build_dir
|
41
|
+
write_cappruby_j_file
|
42
|
+
end
|
43
|
+
|
44
|
+
def cappruby_j_file
|
45
|
+
File.join(build_dir, 'CappRuby.j')
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_cappruby_j_file
|
49
|
+
File.open cappruby_j_file, 'w' do |f|
|
50
|
+
sources = File.join(ROOTPATH, 'framework', '**', '*.js')
|
51
|
+
Dir.glob(sources).each do |s|
|
52
|
+
i = File.read(s)
|
53
|
+
# should really minify
|
54
|
+
f.puts i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|