Skip to content

Commit d67b0a3

Browse files
author
Bradley Meck
committed
Working copy published
0 parents  commit d67b0a3

File tree

3 files changed

+235
-0
lines changed

3 files changed

+235
-0
lines changed

README.TXT

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
node-watchable
2+
@exports
3+
Watchabe(onGet,onSet) - Supplies getter and setter callbacks across all the properties
4+
5+
@example
6+
//print out any property gets that use the . operator
7+
var debug = Watchable(
8+
function(propertyName,value,hadAlready){
9+
//check the type of the object contained by value
10+
//undefined if no value, or number if using []'s with a number
11+
if(typeof value === "string") {
12+
sys.puts(propertyName);
13+
}
14+
return value;
15+
}
16+
function(propertyName,oldValue,value,hadAlready) {
17+
return value;
18+
}
19+
)

overload.cc

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
//
2+
// node-watchable
3+
// @exports
4+
// Watchabe(onGet) - Supplies getter and setter callbacks across all the properties
5+
//
6+
// @example
7+
// //print out any property gets that use the . operator
8+
// var debug = Watchable(function(p,v){if(typeof v == "number") return v; sys.puts(p);return v;})
9+
10+
#include <v8.h>
11+
#include <map>
12+
#include <iostream>
13+
14+
using namespace std;
15+
using namespace v8;
16+
17+
Handle<Value> WatchableNamedPropertyGetter(
18+
Local<String> property
19+
, const AccessorInfo& info
20+
) {
21+
HandleScope scope;
22+
//Grab the value of the property
23+
Handle<Object> holder=info.Holder();
24+
Handle<Value> value;
25+
Handle<Value> had_value;
26+
27+
if(holder->HasRealNamedProperty(property)) {
28+
value = holder->GetRealNamedProperty(property);
29+
had_value = True();
30+
}
31+
else {
32+
value = Undefined();
33+
had_value = False();
34+
}
35+
36+
//Set up arguments
37+
Handle<Value> values[3] = {property,value,had_value};
38+
39+
//Grab function and call (property,value)
40+
Handle<Value> data = holder->GetInternalField(1);
41+
Handle<Function> callback = Handle<Function>::Cast(data);
42+
Handle<Value> new_value = callback->Call(info.Holder(),3,values);
43+
44+
//Return value is the return of the function call
45+
return scope.Close(new_value);
46+
}
47+
48+
Handle<Value> WatchableNamedPropertySetter(
49+
Local<String> property
50+
, Local<Value> value
51+
, const AccessorInfo& info
52+
) {
53+
HandleScope scope;
54+
//Grab the value of the property
55+
Handle<Object> holder=info.Holder();
56+
Handle<Value> old_value;
57+
Handle<Value> had_value;
58+
59+
if(holder->HasRealNamedProperty(property)) {
60+
old_value = holder->GetRealNamedProperty(property);
61+
had_value = True();
62+
}
63+
else {
64+
old_value = Undefined();
65+
had_value = False();
66+
}
67+
68+
//Set up arguments
69+
Handle<Value> values[4] = {property,old_value,value,had_value};
70+
71+
//Grab function and call (property,value)
72+
Handle<Value> data = holder->GetInternalField(2);
73+
Handle<Function> callback = Handle<Function>::Cast(data);
74+
Handle<Value> new_value = callback->Call(info.Holder(),4,values);
75+
76+
holder->ForceSet(property,new_value);
77+
78+
//Return value is the return of the function call
79+
return scope.Close(new_value);
80+
}
81+
82+
Handle<Value> WatchableIndexedPropertyGetter(
83+
uint32_t index
84+
, const AccessorInfo& info
85+
) {
86+
HandleScope scope;
87+
88+
//Grab the value
89+
Handle<Object> holder=info.Holder();
90+
Handle<Number> property = Number::New(index);
91+
Handle<Value> value;
92+
Handle<Value> had_value;
93+
94+
Handle<Object> indices = Handle<Object>::Cast(holder->GetInternalField(0));
95+
if( indices->Has(index) ) {
96+
value =indices->Get(index);
97+
had_value = True();
98+
}
99+
else {
100+
value = Undefined();
101+
had_value = False();
102+
}
103+
//Set up arguments
104+
Handle<Value> values[3] = {property,value,had_value};
105+
106+
//Grab function and call (property,value)
107+
Handle<Value> data = holder->GetInternalField(1);
108+
Handle<Function> callback = Handle<Function>::Cast(data);
109+
Handle<Value> new_value = callback->Call(info.Holder(),3,values);
110+
111+
//Return value is the return of the function call
112+
return scope.Close(new_value);
113+
}
114+
115+
Handle<Value> WatchableIndexedPropertySetter(
116+
uint32_t index
117+
, Local<Value> value
118+
, const AccessorInfo& info
119+
) {
120+
HandleScope scope;
121+
122+
//Grab the value
123+
Handle<Object> holder=info.Holder();
124+
Handle<Number> property = Number::New(index);
125+
Handle<Value> had_value;
126+
127+
Handle<Object> indices = Handle<Object>::Cast(holder->GetInternalField(0));
128+
Handle<Value> old_value;
129+
if( indices->Has(index) ) {
130+
old_value = indices->Get(index);
131+
had_value = True();
132+
}
133+
else {
134+
old_value = Undefined();
135+
had_value = False();
136+
}
137+
138+
//Set up arguments
139+
Handle<Value> values[4] = {property,old_value,value,had_value};
140+
141+
//Grab function and call (property,value)
142+
Handle<Value> data = holder->GetInternalField(2);
143+
Handle<Function> callback = Handle<Function>::Cast(data);
144+
Handle<Value> new_value = callback->Call(info.Holder(),4,values);
145+
146+
indices->Set(index,new_value);
147+
148+
//Return value is the return of the function call
149+
return scope.Close(new_value);
150+
}
151+
152+
153+
Handle<Value> Watchable(const Arguments& args) {
154+
HandleScope scope;
155+
Handle<Value> getter = args[0];
156+
//Check our arguments!
157+
if(getter.IsEmpty() || getter->IsFunction()) {}
158+
else {
159+
return ThrowException(String::New("Getter callback must be a function"));
160+
}
161+
Handle<Value> setter = args[1];
162+
if(setter.IsEmpty() || setter->IsFunction()) {}
163+
else {
164+
return ThrowException(String::New("Getter callback must be a function"));
165+
}
166+
//Every one with a different callback needs a different template
167+
Local<ObjectTemplate> object_template = ObjectTemplate::New();
168+
//0 - Indices object
169+
//1 - Getter
170+
//2 - Setter
171+
//3 - Query
172+
//4 - Deleter
173+
//5 - Enumerator
174+
object_template->SetInternalFieldCount(5);
175+
object_template->SetNamedPropertyHandler(
176+
WatchableNamedPropertyGetter
177+
,WatchableNamedPropertySetter
178+
// ,WatchableNamedPropertyQuery
179+
// ,WatchableNamedPropertyDeleter
180+
// ,WatchableNamedPropertyEnumerator
181+
);
182+
object_template->SetIndexedPropertyHandler(
183+
WatchableIndexedPropertyGetter
184+
,WatchableIndexedPropertySetter
185+
,0,0,0
186+
);
187+
Handle<Object> watchable = object_template->NewInstance();
188+
watchable->SetInternalField(0,Object::New());
189+
watchable->SetInternalField(1,getter);
190+
watchable->SetInternalField(2,setter);
191+
return scope.Close(watchable);
192+
}
193+
194+
extern "C" void init (Handle<Object> target)
195+
{
196+
HandleScope scope;
197+
Local<FunctionTemplate> watchable_template = FunctionTemplate::New(Watchable);
198+
Local<Function> watchable = watchable_template->GetFunction();
199+
//Export
200+
target->Set(String::New("Watchable"),watchable);
201+
}

wscript

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
srcdir = '.'
2+
blddir = 'build'
3+
VERSION = '0.0.1'
4+
5+
def set_options(opt):
6+
opt.tool_options('compiler_cxx')
7+
8+
def configure(conf):
9+
conf.check_tool('compiler_cxx')
10+
conf.check_tool('node_addon')
11+
12+
def build(bld):
13+
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
14+
obj.target = 'overload'
15+
obj.source = 'overload.cc'

0 commit comments

Comments
 (0)