Skip to content

Commit

Permalink
shared: Add cached string optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonMrBonnie committed Oct 2, 2023
1 parent efc7e3c commit eae43a4
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 19 deletions.
18 changes: 9 additions & 9 deletions shared/src/helpers/Convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,25 @@ alt::MValue js::JSToMValue(v8::Local<v8::Value> val, bool allowFunction)
if(resource->IsVector3(v8Obj))
{
alt::Vector3f vec;
vec[0] = obj.Get<float>("x");
vec[1] = obj.Get<float>("y");
vec[2] = obj.Get<float>("z");
vec[0] = obj.Get<float, true>("x");
vec[1] = obj.Get<float, true>("y");
vec[2] = obj.Get<float, true>("z");
return core.CreateMValueVector3(vec);
}
else if(resource->IsVector2(v8Obj))
{
alt::Vector2f vec;
vec[0] = obj.Get<float>("x");
vec[1] = obj.Get<float>("y");
vec[0] = obj.Get<float, true>("x");
vec[1] = obj.Get<float, true>("y");
return core.CreateMValueVector2(vec);
}
else if(resource->IsRGBA(v8Obj))
{
alt::RGBA rgba;
rgba.r = obj.Get<uint8_t>("r");
rgba.g = obj.Get<uint8_t>("g");
rgba.b = obj.Get<uint8_t>("b");
rgba.a = obj.Get<uint8_t>("a");
rgba.r = obj.Get<uint8_t, true>("r");
rgba.g = obj.Get<uint8_t, true>("g");
rgba.b = obj.Get<uint8_t, true>("b");
rgba.a = obj.Get<uint8_t, true>("a");
return core.CreateMValueRGBA(rgba);
}
else if(resource->IsBaseObject(v8Obj))
Expand Down
17 changes: 17 additions & 0 deletions shared/src/helpers/Convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,23 @@ namespace js
alt::MValueByteArray JSToRawBytes(v8::Local<v8::Value> val, IResource* resource);
v8::MaybeLocal<v8::Value> RawBytesToJS(alt::MValueByteArrayConst val, IResource* resource);

// Creates a string that's cached by V8, only use this for constant strings which are commonly used, otherwise it explodes RAM usage!
template<int N>
inline v8::Local<v8::String> CachedString(const char (&val)[N])
{
return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), val, v8::NewStringType::kInternalized, N - 1).ToLocalChecked();
}
inline v8::Local<v8::String> CachedString(const std::string& val)
{
return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), val.data(), v8::NewStringType::kInternalized, (int)val.size()).ToLocalChecked();
}

template<int N>
inline v8::Local<v8::String> JSValue(const char (&val)[N])
{
if constexpr(N == 1) return v8::String::Empty(v8::Isolate::GetCurrent());
return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), val, v8::NewStringType::kNormal, N - 1).ToLocalChecked();
}
inline v8::Local<v8::String> JSValue(const char* val)
{
if(val == nullptr) return v8::String::Empty(v8::Isolate::GetCurrent());
Expand Down
13 changes: 7 additions & 6 deletions shared/src/helpers/JS.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,22 +197,22 @@ namespace js
void SetMethod(const std::string& key, internal::FunctionCallback func);

// Falls back to default value if the value is not found or the type doesn't match
template<typename T>
template<typename T, bool InternalizedString = false>
T Get(const std::string& key, const T& defaultValue = T()) const
{
v8::MaybeLocal<v8::Value> maybeVal = object->Get(context, js::JSValue(key));
v8::MaybeLocal<v8::Value> maybeVal = object->Get(context, InternalizedString ? js::CachedString(key) : js::JSValue(key));
v8::Local<v8::Value> val;
if(!maybeVal.ToLocal(&val)) return defaultValue;
std::optional<T> result = js::CppValue<T>(val);
return result.has_value() ? (T)result.value() : defaultValue;
}

// Throws an error and returns false if the value is not found or the type doesn't match
template<typename T>
template<bool InternalizedString = false, typename T>
bool Get(const std::string& key, T& out, bool throwOnError = true)
{
using Type = std::conditional_t<std::is_enum_v<T>, int, T>;
v8::MaybeLocal<v8::Value> maybeVal = object->Get(context, js::JSValue(key));
v8::MaybeLocal<v8::Value> maybeVal = object->Get(context, InternalizedString ? js::CachedString(key) : js::JSValue(key));
v8::Local<v8::Value> val;
if(!maybeVal.ToLocal(&val))
{
Expand All @@ -229,18 +229,19 @@ namespace js
return true;
}

template<bool InternalizedString = false>
bool GetAsHash(const std::string& key, uint32_t& outValue)
{
Type argType = GetType(key);
if(argType == Type::STRING)
{
std::string val = Get<std::string>(key);
std::string val = Get<std::string, InternalizedString>(key);
outValue = alt::ICore::Instance().Hash(val);
return true;
}
else if(argType == Type::NUMBER)
{
uint32_t val = Get<uint32_t>(key);
uint32_t val = Get<uint32_t, InternalizedString>(key);
outValue = val;
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions shared/src/helpers/ValueBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ bool js::ValueSerializer::Entity(v8::Local<v8::Value>& value)
bool js::ValueSerializer::Vector3(v8::Local<v8::Value>& value)
{
js::Object obj = value.As<v8::Object>();
alt::Vector3f vector{ obj.Get<float>("x"), obj.Get<float>("y"), obj.Get<float>("z") };
alt::Vector3f vector{ obj.Get<float, true>("x"), obj.Get<float, true>("y"), obj.Get<float, true>("z") };

Float(vector[0]);
Float(vector[1]);
Expand All @@ -139,7 +139,7 @@ bool js::ValueSerializer::Vector3(v8::Local<v8::Value>& value)
bool js::ValueSerializer::Vector2(v8::Local<v8::Value>& value)
{
js::Object obj = value.As<v8::Object>();
alt::Vector2f vector{ obj.Get<float>("x"), obj.Get<float>("y") };
alt::Vector2f vector{ obj.Get<float, true>("x"), obj.Get<float, true>("y") };

Float(vector[0]);
Float(vector[1]);
Expand All @@ -149,7 +149,7 @@ bool js::ValueSerializer::Vector2(v8::Local<v8::Value>& value)
bool js::ValueSerializer::RGBA(v8::Local<v8::Value>& value)
{
js::Object obj = value.As<v8::Object>();
alt::RGBA rgba{ obj.Get<uint8_t>("r"), obj.Get<uint8_t>("g"), obj.Get<uint8_t>("b"), obj.Get<uint8_t>("a") };
alt::RGBA rgba{ obj.Get<uint8_t, true>("r"), obj.Get<uint8_t, true>("g"), obj.Get<uint8_t, true>("b"), obj.Get<uint8_t, true>("a") };

Byte(rgba.r);
Byte(rgba.g);
Expand All @@ -161,7 +161,7 @@ bool js::ValueSerializer::RGBA(v8::Local<v8::Value>& value)
bool js::ValueSerializer::Quaternion(v8::Local<v8::Value>& value)
{
js::Object obj = value.As<v8::Object>();
alt::Quaternion quaternion{ obj.Get<float>("x"), obj.Get<float>("y"), obj.Get<float>("z"), obj.Get<float>("w") };
alt::Quaternion quaternion{ obj.Get<float, true>("x"), obj.Get<float, true>("y"), obj.Get<float, true>("z"), obj.Get<float, true>("w") };

Float(quaternion.x);
Float(quaternion.y);
Expand Down

0 comments on commit eae43a4

Please sign in to comment.