|
| 1 | +#include <node.h> |
| 2 | +#include <cstdlib> |
| 3 | + |
| 4 | +using namespace v8; |
| 5 | + |
| 6 | +double Estimate (int points) { |
| 7 | + int i = points; |
| 8 | + int inside = 0; |
| 9 | + unsigned int seed = rand(); |
| 10 | + double r1, r2; |
| 11 | + |
| 12 | + while (i-- > 0) { |
| 13 | + r1 = rand_r(&seed) / (double)RAND_MAX; |
| 14 | + r2 = rand_r(&seed) / (double)RAND_MAX; |
| 15 | + |
| 16 | + if ((r1 * r1) + (r2 * r2) <= 1) |
| 17 | + inside++; |
| 18 | + } |
| 19 | + |
| 20 | + |
| 21 | + return (inside / (double)points) * 4; |
| 22 | +} |
| 23 | + |
| 24 | +Handle<Value> CalculateSync(const Arguments& args) { |
| 25 | + Isolate* isolate = Isolate::GetCurrent(); |
| 26 | + HandleScope scope(isolate); |
| 27 | + |
| 28 | + int points = args[0]->Uint32Value(); |
| 29 | + double est = Estimate(points); |
| 30 | + |
| 31 | + return scope.Close(Number::New(est)); |
| 32 | +} |
| 33 | + |
| 34 | +typedef struct AsyncData { |
| 35 | + int points; |
| 36 | + Persistent<Function> callback; |
| 37 | + double estimate; |
| 38 | +} AsyncData; |
| 39 | + |
| 40 | +void AsyncWork(uv_work_t *req) { |
| 41 | + AsyncData *asyncData = (AsyncData *)req->data; |
| 42 | + asyncData->estimate = Estimate(asyncData->points); |
| 43 | +} |
| 44 | + |
| 45 | +void AsyncAfter(uv_work_t *req) { |
| 46 | + Isolate* isolate = Isolate::GetCurrent(); |
| 47 | + HandleScope scope(isolate); |
| 48 | + |
| 49 | + AsyncData *asyncData = (AsyncData *)req->data; |
| 50 | + Handle<Value> argv[] = { |
| 51 | + Null(), |
| 52 | + Number::New(isolate, asyncData->estimate) |
| 53 | + }; |
| 54 | + |
| 55 | + TryCatch try_catch; |
| 56 | + asyncData->callback->Call(Context::GetCurrent()->Global(), 2, argv); |
| 57 | + asyncData->callback.Dispose(isolate); |
| 58 | + delete asyncData; |
| 59 | + delete req; |
| 60 | + if (try_catch.HasCaught()) |
| 61 | + node::FatalException(try_catch); |
| 62 | +} |
| 63 | + |
| 64 | +Handle<Value> CalculateAsync(const Arguments& args) { |
| 65 | + Isolate* isolate = Isolate::GetCurrent(); |
| 66 | + HandleScope scope(isolate); |
| 67 | + |
| 68 | + uv_work_t *req = new uv_work_t; |
| 69 | + AsyncData *asyncData = new AsyncData; |
| 70 | + req->data = asyncData; |
| 71 | + asyncData->points = args[0]->Uint32Value(); |
| 72 | + Local<Function> callback = Local<Function>::Cast(args[1]); |
| 73 | + asyncData->callback = Persistent<Function>::New(isolate, callback); |
| 74 | + |
| 75 | + uv_queue_work( |
| 76 | + uv_default_loop() |
| 77 | + , req |
| 78 | + , AsyncWork |
| 79 | + , (uv_after_work_cb)AsyncAfter |
| 80 | + ); |
| 81 | + |
| 82 | + return scope.Close(Undefined()); |
| 83 | +} |
| 84 | + |
| 85 | +void InitAll(Handle<Object> exports) { |
| 86 | + exports->Set(String::NewSymbol("calculateSync"), |
| 87 | + FunctionTemplate::New(CalculateSync)->GetFunction()); |
| 88 | + |
| 89 | + exports->Set(String::NewSymbol("calculateAsync"), |
| 90 | + FunctionTemplate::New(CalculateAsync)->GetFunction()); |
| 91 | +} |
| 92 | + |
| 93 | +NODE_MODULE(addon, InitAll) |
0 commit comments