cappruby 0.0.0
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.
- 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
|