diff --git a/server/src/CNodeResourceImpl.cpp b/server/src/CNodeResourceImpl.cpp index a7a1d220..cbb4ff42 100644 --- a/server/src/CNodeResourceImpl.cpp +++ b/server/src/CNodeResourceImpl.cpp @@ -132,8 +132,12 @@ void CNodeResourceImpl::Started(v8::Local _exports) { if(!_exports->IsNullOrUndefined()) { - alt::MValueDict exports = std::dynamic_pointer_cast(V8Helpers::V8ToMValue(_exports)); - resource->SetExports(exports); + auto exports = V8Helpers::V8ToMValue(_exports); + if(exports->GetType() == alt::IMValue::Type::DICT) + resource->SetExports(std::static_pointer_cast(exports)); + else + Log::Warning << "Only object export is supported" << Log::Endl; + envStarted = true; } else diff --git a/server/src/bindings/ConnectionInfo.cpp b/server/src/bindings/ConnectionInfo.cpp index 4e178cee..c831a62a 100644 --- a/server/src/bindings/ConnectionInfo.cpp +++ b/server/src/bindings/ConnectionInfo.cpp @@ -215,8 +215,6 @@ extern V8Class v8ConnectionInfo("ConnectionInfo", { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - V8Helpers::SetStaticMethod(isolate, tpl, "getByID", StaticGetByID); V8Helpers::SetStaticAccessor(isolate, tpl, "all", AllGetter); diff --git a/shared/V8Class.h b/shared/V8Class.h index ecd48c9f..36f46275 100644 --- a/shared/V8Class.h +++ b/shared/V8Class.h @@ -17,6 +17,26 @@ class V8Class std::unordered_map>> tplMap; public: + enum class InternalFields + { + OBJECT_CLASS, + BASE_OBJECT, + RESOURCE, + + COUNT + }; + + enum class ObjectClass + { + NONE, + RESOURCE, + BASE_OBJECT, + VECTOR2, + VECTOR3, + RGBA, + QUATERNION, + }; + static auto& All() { static std::unordered_map _All; diff --git a/shared/V8Entity.h b/shared/V8Entity.h index d79d2934..4affadc6 100644 --- a/shared/V8Entity.h +++ b/shared/V8Entity.h @@ -16,7 +16,8 @@ class V8Entity V8Entity(v8::Local ctx, V8Class* __class, v8::Local obj, alt::IBaseObject* _handle) : _class(__class), handle(_handle) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - obj->SetInternalField(0, v8::External::New(isolate, this)); + V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::BASE_OBJECT); + obj->SetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT), v8::External::New(isolate, this)); jsVal.Reset(isolate, obj); } @@ -40,9 +41,9 @@ class V8Entity if(!val->IsObject()) return nullptr; v8::Local obj = val.As(); - if(obj->InternalFieldCount() != 1) return nullptr; + if(obj->InternalFieldCount() <= static_cast(V8Class::InternalFields::BASE_OBJECT)) return nullptr; - v8::Local i = obj->GetInternalField(0); + v8::Local i = obj->GetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT)); if(!i->IsExternal()) return nullptr; return static_cast(i.As()->Value()); diff --git a/shared/V8Helpers.cpp b/shared/V8Helpers.cpp index a4014d16..5f0d7d11 100644 --- a/shared/V8Helpers.cpp +++ b/shared/V8Helpers.cpp @@ -373,6 +373,22 @@ std::string V8Helpers::GetJSValueTypeName(v8::Local val) return "unknown"; } +void V8Helpers::SetObjectClass(v8::Isolate* isolate, v8::Local obj, V8Class::ObjectClass cls) +{ + obj->SetInternalField( + static_cast(V8Class::InternalFields::OBJECT_CLASS), v8::External::New(isolate, reinterpret_cast(cls)) + ); +} + +V8Class::ObjectClass V8Helpers::GetObjectClass(v8::Local obj) +{ + if(obj->InternalFieldCount() <= static_cast(V8Class::InternalFields::OBJECT_CLASS)) + return V8Class::ObjectClass::NONE; + + void* cls = obj->GetInternalField(static_cast(V8Class::InternalFields::OBJECT_CLASS)).As()->Value(); + return *reinterpret_cast(&cls); +} + v8::MaybeLocal V8Helpers::CallFunctionWithTimeout(v8::Local fn, v8::Local ctx, std::vector>& args, uint32_t timeout) { v8::Isolate* isolate = ctx->GetIsolate(); diff --git a/shared/V8Helpers.h b/shared/V8Helpers.h index 4c835c62..78f24c31 100644 --- a/shared/V8Helpers.h +++ b/shared/V8Helpers.h @@ -174,6 +174,9 @@ namespace V8Helpers std::string Stringify(v8::Local ctx, v8::Local val); std::string GetJSValueTypeName(v8::Local val); + void SetObjectClass(v8::Isolate* isolate, v8::Local obj, V8Class::ObjectClass cls); + V8Class::ObjectClass GetObjectClass(v8::Local obj); + inline std::string GetStackTrace(const std::string errorMsg) { auto isolate = v8::Isolate::GetCurrent(); diff --git a/shared/V8ResourceImpl.cpp b/shared/V8ResourceImpl.cpp index 0ac0851a..7136a70e 100644 --- a/shared/V8ResourceImpl.cpp +++ b/shared/V8ResourceImpl.cpp @@ -218,40 +218,40 @@ v8::Local V8ResourceImpl::CreateRGBA(alt::RGBA rgba) return V8Helpers::New(isolate, GetContext(), rgbaClass.Get(isolate), args); } -bool V8ResourceImpl::IsVector3(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), vector3Class.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsVector2(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), vector2Class.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsQuaternion(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), quaternionClass.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsRGBA(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), rgbaClass.Get(isolate)).To(&result); - return result; -} - -bool V8ResourceImpl::IsBaseObject(v8::Local val) -{ - bool result = false; - val->InstanceOf(GetContext(), baseObjectClass.Get(isolate)).To(&result); - return result; -} +//bool V8ResourceImpl::IsVector3(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), vector3Class.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsVector2(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), vector2Class.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsQuaternion(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), quaternionClass.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsRGBA(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), rgbaClass.Get(isolate)).To(&result); +// return result; +//} +// +//bool V8ResourceImpl::IsBaseObject(v8::Local val) +//{ +// bool result = false; +// val->InstanceOf(GetContext(), baseObjectClass.Get(isolate)).To(&result); +// return result; +//} void V8ResourceImpl::OnCreateBaseObject(alt::IBaseObject* handle) { @@ -285,7 +285,7 @@ void V8ResourceImpl::OnRemoveBaseObject(alt::IBaseObject* handle) } entities.erase(handle); - ent->GetJSVal(isolate)->SetInternalField(0, v8::External::New(isolate, nullptr)); + ent->GetJSVal(isolate)->SetInternalField(static_cast(V8Class::InternalFields::BASE_OBJECT), v8::External::New(isolate, nullptr)); delete ent; } @@ -538,7 +538,8 @@ v8::Local V8ResourceImpl::GetOrCreateResourceObject(alt::IResource* if(resourceObjects.count(resource) != 0) return resourceObjects.at(resource).Get(isolate); // Create instance v8::Local obj = v8Resource.CreateInstance(GetContext()); - obj->SetInternalField(0, v8::External::New(isolate, resource)); + V8Helpers::SetObjectClass(isolate, obj, V8Class::ObjectClass::RESOURCE); + obj->SetInternalField(static_cast(V8Class::InternalFields::RESOURCE), v8::External::New(isolate, resource)); resourceObjects.insert({ resource, V8Helpers::CPersistent(isolate, obj) }); return obj; } @@ -547,7 +548,7 @@ void V8ResourceImpl::DeleteResourceObject(alt::IResource* resource) { if(resourceObjects.count(resource) == 0) return; v8::Local obj = resourceObjects.at(resource).Get(isolate); - obj->SetInternalField(0, v8::External::New(isolate, nullptr)); + obj->SetInternalField(static_cast(V8Class::InternalFields::RESOURCE), v8::External::New(isolate, nullptr)); resourceObjects.erase(resource); } diff --git a/shared/V8ResourceImpl.h b/shared/V8ResourceImpl.h index 01f1c6e2..d921c2f9 100644 --- a/shared/V8ResourceImpl.h +++ b/shared/V8ResourceImpl.h @@ -189,11 +189,11 @@ class V8ResourceImpl : public alt::IResource::Impl v8::Local CreateQuaternion(alt::Quaternion quat); v8::Local CreateRGBA(alt::RGBA rgba); - bool IsVector3(v8::Local val); + /*bool IsVector3(v8::Local val); bool IsVector2(v8::Local val); bool IsQuaternion(v8::Local val); bool IsRGBA(v8::Local val); - bool IsBaseObject(v8::Local val); + bool IsBaseObject(v8::Local val);*/ void OnCreateBaseObject(alt::IBaseObject* handle) override; void OnRemoveBaseObject(alt::IBaseObject* handle) override; diff --git a/shared/bindings/BaseObject.cpp b/shared/bindings/BaseObject.cpp index a3ffa5ac..ad7fbb8e 100644 --- a/shared/bindings/BaseObject.cpp +++ b/shared/bindings/BaseObject.cpp @@ -224,7 +224,7 @@ extern V8Class v8BaseObject("BaseObject", { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetStaticMethod(isolate, tpl, "getByID", StaticGetById); diff --git a/shared/bindings/Blip.cpp b/shared/bindings/Blip.cpp index 7c3f711b..d1fa896d 100644 --- a/shared/bindings/Blip.cpp +++ b/shared/bindings/Blip.cpp @@ -114,13 +114,17 @@ static void ConstructorPointBlip(const v8::FunctionCallbackInfo& info else if(info.Length() == 2) { - if(resource->IsVector3(info[0])) + V8Class::ObjectClass cls = V8Class::ObjectClass::NONE; + if(info[0]->IsObject()) + cls = V8Helpers::GetObjectClass(info[0].As()); + + if(cls == V8Class::ObjectClass::VECTOR3) // TODO: we should allow IVector3 { V8_ARG_TO_VECTOR3(1, pos); V8_ARG_TO_BOOLEAN(2, global); blip = ICore::Instance().CreateBlip(global, alt::IBlip::BlipType::DESTINATION, pos); } - else if(resource->IsBaseObject(info[0])) + else if(cls == V8Class::ObjectClass::BASE_OBJECT) { V8_ARG_TO_BASE_OBJECT(1, ent, IEntity, "entity"); V8_ARG_TO_BOOLEAN(2, global); diff --git a/shared/bindings/Quaternion.cpp b/shared/bindings/Quaternion.cpp index 848337e8..7b9e5eba 100644 --- a/shared/bindings/Quaternion.cpp +++ b/shared/bindings/Quaternion.cpp @@ -12,6 +12,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN2(1, 4); v8::Local _this = info.This(); + V8Helpers::SetObjectClass(isolate, _this, V8Class::ObjectClass::QUATERNION); v8::Local x, y, z, w; @@ -84,7 +85,5 @@ extern V8Class v8Quaternion("Quaternion", Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/bindings/RGBA.cpp b/shared/bindings/RGBA.cpp index 9a838214..e6be1b35 100644 --- a/shared/bindings/RGBA.cpp +++ b/shared/bindings/RGBA.cpp @@ -9,6 +9,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN_MIN_MAX(1, 4); + V8Helpers::SetObjectClass(isolate, info.This(), V8Class::ObjectClass::QUATERNION); int32_t r = 0, g = 0, b = 0, a = 255; if(info.Length() == 1) @@ -70,7 +71,5 @@ extern V8Class v8RGBA("RGBA", &Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/bindings/Resource.cpp b/shared/bindings/Resource.cpp index d5ccb8f3..3837f1f1 100644 --- a/shared/bindings/Resource.cpp +++ b/shared/bindings/Resource.cpp @@ -7,7 +7,7 @@ extern V8Class v8Resource; static void IsStartedGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN(resource->IsStarted()); } @@ -15,7 +15,7 @@ static void IsStartedGetter(v8::Local, const v8::PropertyCallbackInf static void TypeGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetType()); } @@ -23,7 +23,7 @@ static void TypeGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetName()); } @@ -31,7 +31,7 @@ static void NameGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetMain()); } @@ -39,7 +39,7 @@ static void MainGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN(V8Helpers::MValueToV8(resource->GetExports())); } @@ -47,7 +47,7 @@ static void ExportsGetter(v8::Local, const v8::PropertyCallbackInfo< static void DependenciesGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector deps = resource->GetDependencies(); @@ -62,7 +62,7 @@ static void DependenciesGetter(v8::Local, const v8::PropertyCallback static void DependantsGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector deps = resource->GetDependants(); @@ -77,7 +77,7 @@ static void DependantsGetter(v8::Local, const v8::PropertyCallbackIn static void RequiredPermissionsGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector perms = resource->GetRequiredPermissions(); @@ -92,7 +92,7 @@ static void RequiredPermissionsGetter(v8::Local, const v8::PropertyC static void OptionalPermissionsGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); const std::vector perms = resource->GetOptionalPermissions(); @@ -107,7 +107,7 @@ static void OptionalPermissionsGetter(v8::Local, const v8::PropertyC static void ValidGetter(v8::Local, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_RETURN_BOOLEAN(resource != nullptr); } @@ -115,7 +115,7 @@ static void ValidGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); V8_RETURN_STRING(resource->GetPath()); } @@ -124,7 +124,7 @@ static void PathGetter(v8::Local, const v8::PropertyCallbackInfo, const v8::PropertyCallbackInfo& info) { V8_GET_ISOLATE_CONTEXT(); - V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(1, resource, alt::IResource); + V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(static_cast(V8Class::InternalFields::RESOURCE), resource, alt::IResource); V8_CHECK(resource, "Invalid resource"); auto config = resource->GetConfig(); @@ -174,7 +174,7 @@ extern V8Class v8Resource("Resource", { v8::Isolate* isolate = v8::Isolate::GetCurrent(); - tpl->InstanceTemplate()->SetInternalFieldCount(2); // Set it to 2, so that our check for V8 entities works (as this isn't a base object) + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); V8Helpers::SetAccessor(isolate, tpl, "isStarted", &IsStartedGetter); V8Helpers::SetAccessor(isolate, tpl, "type", &TypeGetter); diff --git a/shared/bindings/Vector2.cpp b/shared/bindings/Vector2.cpp index 40925ee8..4ca5095f 100644 --- a/shared/bindings/Vector2.cpp +++ b/shared/bindings/Vector2.cpp @@ -504,6 +504,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN2(1, 2); v8::Local _this = info.This(); + V8Helpers::SetObjectClass(isolate, _this, V8Class::ObjectClass::VECTOR2); v8::Local x, y; @@ -560,7 +561,5 @@ extern V8Class v8Vector2("Vector2", Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/bindings/Vector3.cpp b/shared/bindings/Vector3.cpp index 8df6c17b..dffb8a03 100644 --- a/shared/bindings/Vector3.cpp +++ b/shared/bindings/Vector3.cpp @@ -85,6 +85,7 @@ static void Constructor(const v8::FunctionCallbackInfo& info) V8_CHECK_ARGS_LEN2(1, 3); v8::Local _this = info.This(); + V8Helpers::SetObjectClass(isolate, _this, V8Class::ObjectClass::VECTOR3); v8::Local x, y, z; @@ -149,7 +150,5 @@ extern V8Class v8Vector3("Vector3", Constructor, [](v8::Local tpl) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - - tpl->InstanceTemplate()->SetInternalFieldCount(1); // !! Needs to be set so V8 knows its a custom class !! + tpl->InstanceTemplate()->SetInternalFieldCount(static_cast(V8Class::InternalFields::COUNT)); }); diff --git a/shared/deps/cpp-sdk b/shared/deps/cpp-sdk index 5f49d656..7fe1c8af 160000 --- a/shared/deps/cpp-sdk +++ b/shared/deps/cpp-sdk @@ -1 +1 @@ -Subproject commit 5f49d6564312e8f6f07e5f509f95ba73799cbf6d +Subproject commit 7fe1c8af77fd916a4a3174e947dc0b121022e39e diff --git a/shared/helpers/Serialization.cpp b/shared/helpers/Serialization.cpp index dabce201..6858bf13 100644 --- a/shared/helpers/Serialization.cpp +++ b/shared/helpers/Serialization.cpp @@ -2,10 +2,11 @@ #include "V8ResourceImpl.h" #include "Bindings.h" #include "CProfiler.h" +#include "V8Helpers.h" alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) { - CProfiler::Sample _("V8Helpers::V8ToMValue", true); + // CProfiler::Sample _("V8Helpers::V8ToMValue", true); alt::ICore& core = alt::ICore::Instance(); v8::Isolate* isolate = v8::Isolate::GetCurrent(); @@ -100,10 +101,11 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) else { V8ResourceImpl* resource = V8ResourceImpl::Get(ctx); - v8::Local v8Obj = val.As(); + auto v8Obj = val.As(); + auto cls = V8Helpers::GetObjectClass(v8Obj); - // if (v8Obj->InstanceOf(ctx, v8Vector3->JSValue(isolate, ctx)).ToChecked()) - if(resource->IsVector3(v8Obj)) + //// if (v8Obj->InstanceOf(ctx, v8Vector3->JSValue(isolate, ctx)).ToChecked()) + if(cls == V8Class::ObjectClass::VECTOR3) { v8::Local x, y, z; V8_CHECK_RETN(v8Obj->Get(ctx, resource->XKey()).ToLocal(&x), "Failed to convert Vector3 to MValue", core.CreateMValueNil()); @@ -112,7 +114,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) return core.CreateMValueVector3(alt::Vector3f{ x.As()->Value(), y.As()->Value(), z.As()->Value() }); } - else if(resource->IsVector2(v8Obj)) + if(cls == V8Class::ObjectClass::VECTOR2) { v8::Local x, y; V8_CHECK_RETN(v8Obj->Get(ctx, resource->XKey()).ToLocal(&x), "Failed to convert Vector2 to MValue", core.CreateMValueNil()); @@ -120,7 +122,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) return core.CreateMValueVector2(alt::Vector2f{ x.As()->Value(), y.As()->Value() }); } - else if(resource->IsRGBA(v8Obj)) + else if(cls == V8Class::ObjectClass::RGBA) { v8::Local r, g, b, a; V8_CHECK_RETN(v8Obj->Get(ctx, resource->RKey()).ToLocal(&r), "Failed to convert RGBA to MValue", core.CreateMValueNil()); @@ -131,7 +133,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) return core.CreateMValueRGBA( alt::RGBA{ (uint8_t)r.As()->Value(), (uint8_t)g.As()->Value(), (uint8_t)b.As()->Value(), (uint8_t)a.As()->Value() }); } - else if(resource->IsBaseObject(v8Obj)) + else if(cls == V8Class::ObjectClass::BASE_OBJECT) { V8Entity* ent = V8Entity::Get(v8Obj); @@ -152,7 +154,7 @@ alt::MValue V8Helpers::V8ToMValue(v8::Local val, bool allowFunction) V8_CHECK_RETN(v8Obj->Get(ctx, v8Key).ToLocal(&value), "Failed to convert object to MValue", core.CreateMValueNil()); if(value->IsUndefined()) continue; - std::string key = *v8::String::Utf8Value(isolate, v8Key); + auto key = *v8::String::Utf8Value(isolate, v8Key); dict->Set(key, V8ToMValue(value, allowFunction)); } @@ -177,10 +179,10 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) { case alt::IMValue::Type::NONE: return v8::Undefined(isolate); case alt::IMValue::Type::NIL: return V8Helpers::JSValue(nullptr); - case alt::IMValue::Type::BOOL: return V8Helpers::JSValue(std::dynamic_pointer_cast(val)->Value()); + case alt::IMValue::Type::BOOL: return V8Helpers::JSValue(std::static_pointer_cast(val)->Value()); case alt::IMValue::Type::INT: { - int64_t _val = std::dynamic_pointer_cast(val)->Value(); + int64_t _val = std::static_pointer_cast(val)->Value(); if(_val >= JS_MIN_SAFE_INTEGER && _val <= JS_MAX_SAFE_INTEGER) return V8Helpers::JSValue((double)_val); @@ -188,17 +190,17 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) } case alt::IMValue::Type::UINT: { - uint64_t _val = std::dynamic_pointer_cast(val)->Value(); + uint64_t _val = std::static_pointer_cast(val)->Value(); if(_val <= JS_MAX_SAFE_INTEGER) return V8Helpers::JSValue((double)_val); return V8Helpers::JSValue(_val); } - case alt::IMValue::Type::DOUBLE: return V8Helpers::JSValue(std::dynamic_pointer_cast(val)->Value()); - case alt::IMValue::Type::STRING: return V8Helpers::JSValue(std::dynamic_pointer_cast(val)->Value()); + case alt::IMValue::Type::DOUBLE: return V8Helpers::JSValue(std::static_pointer_cast(val)->Value()); + case alt::IMValue::Type::STRING: return V8Helpers::JSValue(std::static_pointer_cast(val)->Value()); case alt::IMValue::Type::LIST: { - alt::MValueListConst list = std::dynamic_pointer_cast(val); + alt::MValueListConst list = std::static_pointer_cast(val); v8::Local v8Arr = v8::Array::New(isolate, (int)list->GetSize()); for(uint32_t i = 0; i < list->GetSize(); ++i) v8Arr->Set(ctx, i, MValueToV8(list->Get(i))); @@ -207,7 +209,7 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) } case alt::IMValue::Type::DICT: { - alt::MValueDictConst dict = std::dynamic_pointer_cast(val); + alt::MValueDictConst dict = std::static_pointer_cast(val); v8::Local v8Obj = v8::Object::New(isolate); for(auto it = dict->Begin(); it != dict->End(); ++it) @@ -219,24 +221,24 @@ v8::Local V8Helpers::MValueToV8(alt::MValueConst val) } case alt::IMValue::Type::BASE_OBJECT: { - alt::IBaseObject* ref = std::dynamic_pointer_cast(val)->RawValue(); + alt::IBaseObject* ref = std::static_pointer_cast(val)->RawValue(); return V8ResourceImpl::Get(ctx)->GetBaseObjectOrNull(ref); } case alt::IMValue::Type::FUNCTION: { - alt::MValueFunctionConst fn = std::dynamic_pointer_cast(val); + alt::MValueFunctionConst fn = std::static_pointer_cast(val); v8::Local extFn = v8::External::New(isolate, new alt::MValueFunctionConst(fn)); v8::Local func; V8_CHECK_RETN(v8::Function::New(ctx, V8Helpers::FunctionCallback, extFn).ToLocal(&func), "Failed to convert MValue to function", v8::Undefined(isolate)); return func; } - case alt::IMValue::Type::VECTOR3: return V8ResourceImpl::Get(ctx)->CreateVector3(std::dynamic_pointer_cast(val)->Value()); - case alt::IMValue::Type::VECTOR2: return V8ResourceImpl::Get(ctx)->CreateVector2(std::dynamic_pointer_cast(val)->Value()); - case alt::IMValue::Type::RGBA: return V8ResourceImpl::Get(ctx)->CreateRGBA(std::dynamic_pointer_cast(val)->Value()); + case alt::IMValue::Type::VECTOR3: return V8ResourceImpl::Get(ctx)->CreateVector3(std::static_pointer_cast(val)->Value()); + case alt::IMValue::Type::VECTOR2: return V8ResourceImpl::Get(ctx)->CreateVector2(std::static_pointer_cast(val)->Value()); + case alt::IMValue::Type::RGBA: return V8ResourceImpl::Get(ctx)->CreateRGBA(std::static_pointer_cast(val)->Value()); case alt::IMValue::Type::BYTE_ARRAY: { - alt::MValueByteArrayConst buffer = std::dynamic_pointer_cast(val); + alt::MValueByteArrayConst buffer = std::static_pointer_cast(val); // Check if the buffer is a raw JS value buffer v8::MaybeLocal jsVal = RawBytesToV8(buffer); if(!jsVal.IsEmpty()) return jsVal.ToLocalChecked(); @@ -283,11 +285,18 @@ static inline RawValueType GetValueType(v8::Local ctx, v8::LocalIsVector3(val)) return RawValueType::VECTOR3; - if(resource->IsVector2(val)) return RawValueType::VECTOR2; - if(resource->IsRGBA(val)) return RawValueType::RGBA; - else - return RawValueType::GENERIC; + + if(val->IsObject()) + { + switch(V8Helpers::GetObjectClass(val.As())) + { + case V8Class::ObjectClass::VECTOR3: return RawValueType::VECTOR3; + case V8Class::ObjectClass::VECTOR2: return RawValueType::VECTOR2; + case V8Class::ObjectClass::RGBA: return RawValueType::RGBA; + } + } + + return RawValueType::GENERIC; } static inline bool WriteRawValue(v8::Local ctx, v8::ValueSerializer& serializer, RawValueType type, v8::Local val)