Skip to content

Commit

Permalink
[Enhancement] remove boost-variant (opentibiabr#722)
Browse files Browse the repository at this point in the history
Removal of boost::variant and derivatives, reducing the amount of libs the project needs to compile.
A rework was performed on the "struct CustomAttribute", to remove the generic types that were used in boost::variant, which could also cause an increase in memory usage.
  • Loading branch information
dudantas authored and jacksonie committed Feb 17, 2023
1 parent df2d351 commit a7f2ef3
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 204 deletions.
9 changes: 4 additions & 5 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3499,8 +3499,7 @@ void Game::playerWrapableItem(uint32_t playerId, const Position& pos, uint8_t st
const ItemAttributes::CustomAttribute* attr = item->getCustomAttribute("unWrapId");
uint16_t unWrapId = 0;
if (attr != nullptr) {
uint32_t tmp = static_cast<uint32_t>(boost::get<int64_t>(attr->value));
unWrapId = (uint16_t)tmp;
unWrapId = static_cast<uint16_t>(attr->getInt());
}

// Prevent to wrap a filled bath tube
Expand All @@ -3517,10 +3516,10 @@ void Game::playerWrapableItem(uint32_t playerId, const Position& pos, uint8_t st
uint16_t oldItemID = item->getID();
addMagicEffect(item->getPosition(), CONST_ME_POFF);
Item* newItem = transformItem(item, ITEM_DECORATION_KIT);
ItemAttributes::CustomAttribute val;
val.set<int64_t>(oldItemID);
ItemAttributes::CustomAttribute customAttribute;
customAttribute.setInt64(oldItemID);
std::string key = "unWrapId";
newItem->setCustomAttribute(key, val);
newItem->setCustomAttribute(key, customAttribute);
item->setSpecialDescription("Unwrap it in your own house to create a <" + itemName + ">.");
if (hiddenCharges > 0) {
item->setDate(hiddenCharges);
Expand Down
14 changes: 7 additions & 7 deletions src/items/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Item* Item::CreateItem(const uint16_t type, uint16_t count /*= 0*/)
bool Item::getImbuementInfo(uint8_t slot, ImbuementInfo *imbuementInfo)
{
const ItemAttributes::CustomAttribute* attribute = getCustomAttribute(IMBUEMENT_SLOT + slot);
uint32_t info = attribute ? static_cast<uint32_t>(attribute->getInt()) : 0;
auto info = attribute ? static_cast<uint32_t>(attribute->getInt()) : 0;
imbuementInfo->imbuement = g_imbuements().getImbuement(info & 0xFF);
imbuementInfo->duration = info >> 8;
return imbuementInfo->duration && imbuementInfo->imbuement;
Expand All @@ -96,9 +96,9 @@ bool Item::getImbuementInfo(uint8_t slot, ImbuementInfo *imbuementInfo)
void Item::setImbuement(uint8_t slot, uint16_t imbuementId, int32_t duration)
{
std::string key = boost::lexical_cast<std::string>(IMBUEMENT_SLOT + slot);
ItemAttributes::CustomAttribute value;
value.set<int64_t>(duration > 0 ? (duration << 8) | imbuementId : 0);
setCustomAttribute(key, value);
ItemAttributes::CustomAttribute customAttribute;
customAttribute.setInt64(duration > 0 ? (duration << 8) | imbuementId : 0);
setCustomAttribute(key, customAttribute);
}

void Item::addImbuement(uint8_t slot, uint16_t imbuementId, int32_t duration)
Expand Down Expand Up @@ -752,12 +752,12 @@ Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream& propStream)
};

// Unserialize value type and value
ItemAttributes::CustomAttribute val;
if (!val.unserialize(propStream)) {
ItemAttributes::CustomAttribute customAttribute;
if (!customAttribute.unserialize(propStream)) {
return ATTR_READ_ERROR;
}

setCustomAttribute(key, val);
setCustomAttribute(key, customAttribute);
}
break;
}
Expand Down
189 changes: 85 additions & 104 deletions src/items/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,152 +150,121 @@ class ItemAttributes

struct CustomAttribute
{
typedef boost::variant<boost::blank, std::string, int64_t, double, bool> VariantAttribute;
VariantAttribute value;
std::string stringValue;
int64_t intValue;
bool boolValue;
double doubleValue;
bool hasStringValue = false;
bool hasIntValue = false;
bool hasBoolValue = false;
bool hasDoubleValue = false;

CustomAttribute() = default;

void setString(const std::string& string) {
stringValue = string;
hasStringValue = true;
}

CustomAttribute() : value(boost::blank()) {}
void setInt64(int64_t int64) {
intValue = int64;
hasIntValue = true;
}

template<typename T>
explicit CustomAttribute(const T& v) : value(v) {}
void setDouble(double newDouble) {
doubleValue = newDouble;
hasDoubleValue = true;
}

template<typename T>
void set(const T& v) {
value = v;
void setBool(bool boolean) {
boolValue = boolean;
hasBoolValue = true;
}

const std::string& getString() const {
if (value.type() == typeid(std::string)) {
return boost::get<std::string>(value);
}

return emptyString;
return stringValue;
}

const int64_t& getInt() const {
if (value.type() == typeid(int64_t)) {
return boost::get<int64_t>(value);
}

return emptyInt;
int64_t getInt() const {
return intValue;
}

const double& getDouble() const {
if (value.type() == typeid(double)) {
return boost::get<double>(value);
}

return emptyDouble;
bool getBool() const {
return boolValue;
}

const bool& getBool() const {
if (value.type() == typeid(bool)) {
return boost::get<bool>(value);
}

return emptyBool;
bool hasValue() const {
return hasStringValue || hasIntValue || hasBoolValue || hasDoubleValue;
}

struct PushLuaVisitor : public boost::static_visitor<> {
lua_State* L;

explicit PushLuaVisitor(lua_State* L) : boost::static_visitor<>(), L(L) {}

void operator()(const boost::blank&) const {
void pushToLua(lua_State* L) const {
if (hasStringValue) {
LuaScriptInterface::pushString(L, stringValue);
} else if (hasIntValue) {
lua_pushnumber(L, static_cast<lua_Number>(intValue));
} else if (hasDoubleValue) {
lua_pushnumber(L, doubleValue);
} else if (hasBoolValue) {
LuaScriptInterface::pushBoolean(L, boolValue);
} else {
lua_pushnil(L);
}

void operator()(const std::string& v) const {
LuaScriptInterface::pushString(L, v);
}

void operator()(bool v) const {
LuaScriptInterface::pushBoolean(L, v);
}

void operator()(const int64_t& v) const {
lua_pushnumber(L, v);
}

void operator()(const double& v) const {
lua_pushnumber(L, v);
}
};

void pushToLua(lua_State* L) const {
boost::apply_visitor(PushLuaVisitor(L), value);
}

struct SerializeVisitor : public boost::static_visitor<> {
PropWriteStream& propWriteStream;

explicit SerializeVisitor(PropWriteStream& propWriteStream) : boost::static_visitor<>(), propWriteStream(propWriteStream) {}

void operator()(const boost::blank&) const {
}

void operator()(const std::string& v) const {
propWriteStream.writeString(v);
}

template<typename T>
void operator()(const T& v) const {
propWriteStream.write<T>(v);
}
};

void serialize(PropWriteStream& propWriteStream) const {
propWriteStream.write<uint8_t>(static_cast<uint8_t>(value.which()));
boost::apply_visitor(SerializeVisitor(propWriteStream), value);
if (hasStringValue) {
propWriteStream.write<uint8_t>(1);
propWriteStream.writeString(stringValue);
} else if (hasIntValue) {
propWriteStream.write<uint8_t>(2);
} else if (hasDoubleValue) {
propWriteStream.write<uint8_t>(3);
} else if (hasBoolValue) {
propWriteStream.write<uint8_t>(4);
}
}

bool unserialize(PropStream& propStream) {
// This is hard coded so it's not general, depends on the position of the variants.
uint8_t pos;
if (!propStream.read<uint8_t>(pos)) {
uint8_t type;
if (!propStream.read<uint8_t>(type)) {
return false;
}

switch (pos) {
case 1: { // std::string
std::string tmp;
if (!propStream.readString(tmp)) {
switch (type) {
case 1: {
std::string readString;
if (!propStream.readString(readString)) {
return false;
}
value = tmp;
setString(readString);
break;
}

case 2: { // int64_t
int64_t tmp;
if (!propStream.read<int64_t>(tmp)) {
case 2: {
int64_t readInt;
if (!propStream.read<int64_t>(readInt)) {
return false;
}
value = tmp;
setInt64(readInt);
break;
}

case 3: { // double
double tmp;
if (!propStream.read<double>(tmp)) {
case 3: {
double readDouble;
if (!propStream.read<double>(readDouble)) {
return false;
}
value = tmp;
setDouble(readDouble);
break;
}

case 4: { // bool
bool tmp;
if (!propStream.read<bool>(tmp)) {
case 4: {
bool readBoolean;
if (!propStream.read<bool>(readBoolean)) {
return false;
}
value = tmp;
setBool(readBoolean);
break;
}

default: {
value = boost::blank();
default:
return false;
}
}
return true;
}
Expand Down Expand Up @@ -411,6 +380,18 @@ class ItemAttributes
}
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom->emplace(key, value);
}
void setCustomAttribute(std::string& key, int64_t intValue) {
toLowerCaseString(key);
if (hasAttribute(ITEM_ATTRIBUTE_CUSTOM)) {
removeCustomAttribute(key);
} else {
auto newAttribute = std::make_unique<CustomAttributeMap>();
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom = newAttribute.get();
}
ItemAttributes::CustomAttribute customAttribute;
customAttribute.setInt64(intValue);
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom->emplace(key, customAttribute);
}

void setCustomAttribute(std::string& key, CustomAttribute& value) {
toLowerCaseString(key);
Expand Down
16 changes: 8 additions & 8 deletions src/lua/functions/items/item_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,24 +515,24 @@ int ItemFunctions::luaItemSetCustomAttribute(lua_State* L) {
return 1;
}

ItemAttributes::CustomAttribute val;
ItemAttributes::CustomAttribute attribute;
if (isNumber(L, 3)) {
double tmp = getNumber<double>(L, 3);
if (std::floor(tmp) < tmp) {
val.set<double>(tmp);
double doubleValue = getNumber<double>(L, 3);
if (std::floor(doubleValue) < doubleValue) {
attribute.setDouble(doubleValue);
} else {
val.set<int64_t>(tmp);
attribute.setInt64(getNumber<int64_t>(L, 3));
}
} else if (isString(L, 3)) {
val.set<std::string>(getString(L, 3));
attribute.setString(getString(L, 3));
} else if (isBoolean(L, 3)) {
val.set<bool>(getBoolean(L, 3));
attribute.setBool(getBoolean(L, 3));
} else {
lua_pushnil(L);
return 1;
}

item->setCustomAttribute(key, val);
item->setCustomAttribute(key, attribute);
pushBoolean(L, true);
return 1;
}
Expand Down
6 changes: 3 additions & 3 deletions src/map/house/house.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,10 @@ bool House::transferToDepot(Player* player) const
std::string itemName = item->getName();
uint16_t itemID = item->getID();
Item* newItem = g_game().transformItem(item, ITEM_DECORATION_KIT);
ItemAttributes::CustomAttribute val;
val.set<int64_t>(itemID);
ItemAttributes::CustomAttribute attribute;
attribute.setInt64(itemID);
std::string key = "unWrapId";
newItem->setCustomAttribute(key, val);
newItem->setCustomAttribute(key, attribute);
std::ostringstream ss;
ss << "Unwrap it in your own house to create a <" << itemName << ">.";
newItem->setStrAttr(ITEM_ATTRIBUTE_DESCRIPTION, ss.str());
Expand Down
1 change: 0 additions & 1 deletion src/pch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/variant.hpp>
#include <curl/curl.h>
#include <fmt/chrono.h>
#include <gmp.h>
Expand Down
Loading

0 comments on commit a7f2ef3

Please sign in to comment.