void JavaObject::wrap(Handle<Object> jsObject) { ASSERT(handle_.IsEmpty()); ASSERT(jsObject->InternalFieldCount() > 0); handle_ = v8::Persistent<v8::Object>::New(jsObject); handle_->SetPointerInInternalField(0, this); }
v8::Handle<v8::Value> v8Sprite::RenderTo(const v8::Arguments &args) { HandleScope scope; v8Sprite *spriteWrapper = ObjectWrap::Unwrap<v8Sprite>(args.Holder()); if (NULL == spriteWrapper) { return ThrowException(v8::Exception::ReferenceError(String::NewSymbol( "Sprite::renderTo(): NULL Holder." ))); } // This is kinda strange, but I can't think of a simpler way to handle // dynamically accepting both Canvas and Window in a secure (e.g. not // depending on (mutable) JavaScript state to determine which to use) way. // We'll manually unwrap the internal pointer, and use RTTI to determine // which class of instance we have been passed. Handle<Object> instanceHandle = args[0]->ToObject(); if (instanceHandle.IsEmpty() || 0 == instanceHandle->InternalFieldCount()) { return ThrowException(v8::Exception::ReferenceError(String::NewSymbol( "Sprite::render(): NULL destination." ))); } ObjectWrap *instance = static_cast<ObjectWrap *>( instanceHandle->GetAlignedPointerFromInternalField(0) ); v8Canvas *destinationCanvas = dynamic_cast<v8Canvas *>(instance); v8Window *destinationWindow = dynamic_cast<v8Window *>(instance); if (destinationCanvas) { spriteWrapper->sprite->renderTo(destinationCanvas->wrappedCanvas()); } else { spriteWrapper->sprite->renderTo(destinationWindow->wrappedWindow()); } return v8::Undefined(); }
jsvalue JsEngine::AnyFromV8(Handle<Value> value, Handle<Object> thisArg) { jsvalue v; // Initialize to a generic error. v.type = JSVALUE_TYPE_UNKNOWN_ERROR; v.length = 0; v.value.str = 0; if (value->IsNull() || value->IsUndefined()) { v.type = JSVALUE_TYPE_NULL; } else if (value->IsBoolean()) { v.type = JSVALUE_TYPE_BOOLEAN; v.value.i32 = value->BooleanValue() ? 1 : 0; } else if (value->IsInt32()) { v.type = JSVALUE_TYPE_INTEGER; v.value.i32 = value->Int32Value(); } else if (value->IsUint32()) { v.type = JSVALUE_TYPE_INDEX; v.value.i64 = value->Uint32Value(); } else if (value->IsNumber()) { v.type = JSVALUE_TYPE_NUMBER; v.value.num = value->NumberValue(); } else if (value->IsString()) { v = StringFromV8(value); } else if (value->IsDate()) { v.type = JSVALUE_TYPE_DATE; v.value.num = value->NumberValue(); } else if (value->IsArray()) { Handle<Array> object = Handle<Array>::Cast(value->ToObject()); v.length = object->Length(); jsvalue* array = new jsvalue[v.length]; if (array != NULL) { for(int i = 0; i < v.length; i++) { array[i] = AnyFromV8(object->Get(i)); } v.type = JSVALUE_TYPE_ARRAY; v.value.arr = array; } } else if (value->IsFunction()) { Handle<Function> function = Handle<Function>::Cast(value); jsvalue* array = new jsvalue[2]; if (array != NULL) { array[0].value.ptr = new Persistent<Object>(Persistent<Function>::New(function)); array[0].length = 0; array[0].type = JSVALUE_TYPE_WRAPPED; if (!thisArg.IsEmpty()) { array[1].value.ptr = new Persistent<Object>(Persistent<Object>::New(thisArg)); array[1].length = 0; array[1].type = JSVALUE_TYPE_WRAPPED; } else { array[1].value.ptr = NULL; array[1].length = 0; array[1].type = JSVALUE_TYPE_NULL; } v.type = JSVALUE_TYPE_FUNCTION; v.value.arr = array; } } else if (value->IsObject()) { Handle<Object> obj = Handle<Object>::Cast(value); if (obj->InternalFieldCount() == 1) v = ManagedFromV8(obj); else v = WrappedFromV8(obj); } return v; }