-
Notifications
You must be signed in to change notification settings - Fork 12
/
cocoa_bridgesupport.m
136 lines (112 loc) · 3.57 KB
/
cocoa_bridgesupport.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//
// BridgeSupport support
//
// See Copyright Notice in cocoa.h
//
#include "cocoa_bridgesupport.h"
#include "cocoa_type.h"
#include "cocoa.h"
#include "cfunc.h"
#include "cfunc_struct.h"
#include "cfunc_pointer.h"
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/variable.h"
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
void
load_cocoa_bridgesupport(mrb_state *mrb,
struct BridgeSupportStructTable *struct_table,
struct BridgeSupportConstTable *const_table,
struct BridgeSupportEnumTable *enum_table)
{
struct cocoa_state *cs = cocoa_state(mrb, NULL);
cs->struct_table = struct_table;
cs->const_table = const_table;
cs->enum_table = enum_table;
}
// Need to re-write to hash table
const char*
cocoa_bridgesupport_struct_lookup(mrb_state *mrb, const char *name)
{
if(cocoa_state(mrb, NULL)->struct_table == NULL) {
return NULL;
}
struct BridgeSupportStructTable *cur = cocoa_state(mrb, NULL)->struct_table;
while(cur->name) {
if(strcmp(name, cur->name)==0) {
return cur->definition;
}
++cur;
}
return NULL;
}
mrb_value
cocoa_struct_const_missing(mrb_state *mrb, mrb_value klass)
{
if(cocoa_state(mrb, NULL)->const_table == NULL) {
return mrb_nil_value();
}
mrb_value name;
mrb_get_args(mrb, "o", &name);
char *namestr = mrb_string_value_ptr(mrb, name);
const char *definition = cocoa_bridgesupport_struct_lookup(mrb, namestr);
if(definition) {
char *type = malloc(strlen(namestr) + 4);
strcpy(type, "{");
strcat(type, namestr);
strcat(type, "=}");
mrb_value strct = objc_type_to_cfunc_type(mrb, type);
mrb_define_const(mrb, (struct RClass*)mrb_object(klass), namestr, strct);
return strct;
}
else {
// todo: raise unknow struct exception
printf("Unknown %s\n", namestr);
return mrb_nil_value();
}
}
mrb_value
cocoa_const_const_missing(mrb_state *mrb, mrb_value klass)
{
if(cocoa_state(mrb, NULL)->const_table == NULL) {
return mrb_nil_value();
}
mrb_value name;
mrb_get_args(mrb, "o", &name);
char *namestr = mrb_string_value_ptr(mrb, name);
struct BridgeSupportConstTable *ccur = cocoa_state(mrb, NULL)->const_table;
while(ccur->name) {
if(strcmp(namestr, ccur->name)==0) {
mrb_value type = objc_type_to_cfunc_type(mrb, ccur->type);
mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, ccur->value, false);
return mrb_funcall(mrb, type, "refer", 1, ptr);
}
++ccur;
}
struct BridgeSupportEnumTable *ecur = cocoa_state(mrb, NULL)->enum_table;
while(ecur->name) {
if(strcmp(namestr, ecur->name)==0) {
return ecur->value;
}
++ecur;
}
return mrb_nil_value();
}
/*
* initialize function
*/
void
init_cocoa_bridge_support(mrb_state *mrb, struct RClass* module)
{
struct cocoa_state *cs = cocoa_state(mrb, module);
struct RClass *struct_module = mrb_define_module_under(mrb, module, "Struct");
mrb_define_class_method(mrb, struct_module, "const_missing", cocoa_struct_const_missing, ARGS_REQ(1));
struct RClass *const_module = mrb_define_module_under(mrb, module, "Const");
mrb_define_class_method(mrb, const_module, "const_missing", cocoa_const_const_missing, ARGS_REQ(1));
mrb_define_class_method(mrb, const_module, "method_missing", cocoa_const_const_missing, ARGS_REQ(1));
cs->struct_module = struct_module;
cs->const_module = const_module;
cs->const_table = NULL;
cs->struct_table = NULL;
}