Skip to content

Commit

Permalink
chore: Move database storage containers to be translation unit local …
Browse files Browse the repository at this point in the history
…to allow for safe references (#1434)

* Move CDClientManager to be a namespace

Tested that worlds still load data as expected.  Had no use being a singleton anyways.

* Move cdclient data storage to tu local containers

Allows some data from these containers to be saved on object by reference instead of always needing to copy.

iteration 2

- move all unnamed namespace containers to a singular spot
- use macro for template specialization and variable declaration
- use templates to allow for as little copy paste of types and functions as possible

* remember to use typename!

compiler believes T::StorageType is accessing a member, not a type.

* Update CDClientManager.cpp

* move to cpp?
  • Loading branch information
EmosewaMC authored Feb 9, 2024
1 parent dc29f59 commit d2aeebc
Show file tree
Hide file tree
Showing 84 changed files with 394 additions and 529 deletions.
50 changes: 50 additions & 0 deletions dDatabase/CDClientDatabase/CDClientManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "CDFeatureGatingTable.h"
#include "CDRailActivatorComponent.h"
#include "CDRewardCodesTable.h"
#include "CDPetComponentTable.h"

#include <exception>

Expand All @@ -61,6 +62,55 @@ class CDClientConnectionException : public std::exception {
}
};

// Using a macro to reduce repetitive code and issues from copy and paste.
// As a note, ## in a macro is used to concatenate two tokens together.

#define SPECIALIZE_TABLE_STORAGE(table) \
template<> typename table::StorageType& CDClientManager::GetEntriesMutable<table>() { return table##Entries; };

#define DEFINE_TABLE_STORAGE(table) namespace { table::StorageType table##Entries; }; SPECIALIZE_TABLE_STORAGE(table)

DEFINE_TABLE_STORAGE(CDActivityRewardsTable);
DEFINE_TABLE_STORAGE(CDActivitiesTable);
DEFINE_TABLE_STORAGE(CDAnimationsTable);
DEFINE_TABLE_STORAGE(CDBehaviorParameterTable);
DEFINE_TABLE_STORAGE(CDBehaviorTemplateTable);
DEFINE_TABLE_STORAGE(CDBrickIDTableTable);
DEFINE_TABLE_STORAGE(CDComponentsRegistryTable);
DEFINE_TABLE_STORAGE(CDCurrencyTableTable);
DEFINE_TABLE_STORAGE(CDDestructibleComponentTable);
DEFINE_TABLE_STORAGE(CDEmoteTableTable);
DEFINE_TABLE_STORAGE(CDFeatureGatingTable);
DEFINE_TABLE_STORAGE(CDInventoryComponentTable);
DEFINE_TABLE_STORAGE(CDItemComponentTable);
DEFINE_TABLE_STORAGE(CDItemSetSkillsTable);
DEFINE_TABLE_STORAGE(CDItemSetsTable);
DEFINE_TABLE_STORAGE(CDLevelProgressionLookupTable);
DEFINE_TABLE_STORAGE(CDLootMatrixTable);
DEFINE_TABLE_STORAGE(CDLootTableTable);
DEFINE_TABLE_STORAGE(CDMissionEmailTable);
DEFINE_TABLE_STORAGE(CDMissionNPCComponentTable);
DEFINE_TABLE_STORAGE(CDMissionTasksTable);
DEFINE_TABLE_STORAGE(CDMissionsTable);
DEFINE_TABLE_STORAGE(CDMovementAIComponentTable);
DEFINE_TABLE_STORAGE(CDObjectSkillsTable);
DEFINE_TABLE_STORAGE(CDObjectsTable);
DEFINE_TABLE_STORAGE(CDPhysicsComponentTable);
DEFINE_TABLE_STORAGE(CDPackageComponentTable);
DEFINE_TABLE_STORAGE(CDPetComponentTable);
DEFINE_TABLE_STORAGE(CDProximityMonitorComponentTable);
DEFINE_TABLE_STORAGE(CDPropertyEntranceComponentTable);
DEFINE_TABLE_STORAGE(CDPropertyTemplateTable);
DEFINE_TABLE_STORAGE(CDRailActivatorComponentTable);
DEFINE_TABLE_STORAGE(CDRarityTableTable);
DEFINE_TABLE_STORAGE(CDRebuildComponentTable);
DEFINE_TABLE_STORAGE(CDRewardCodesTable);
DEFINE_TABLE_STORAGE(CDRewardsTable);
DEFINE_TABLE_STORAGE(CDScriptComponentTable);
DEFINE_TABLE_STORAGE(CDSkillBehaviorTable);
DEFINE_TABLE_STORAGE(CDVendorComponentTable);
DEFINE_TABLE_STORAGE(CDZoneTableTable);

void CDClientManager::LoadValuesFromDatabase() {
if (!CDClientDatabase::isConnected) throw CDClientConnectionException();

Expand Down
34 changes: 26 additions & 8 deletions dDatabase/CDClientDatabase/CDClientManager.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#pragma once

#include "CDTable.h"

#include "Singleton.h"
#ifndef __CDCLIENTMANAGER__H__
#define __CDCLIENTMANAGER__H__

#define UNUSED_TABLE(v)

Expand All @@ -20,7 +17,28 @@ namespace CDClientManager {
* @return A pointer to the requested table.
*/
template<typename T>
T* GetTable() {
return &T::Instance();
}
T* GetTable();

/**
* Fetch a table from CDClient
* Note: Calling this function without a template specialization in CDClientManager.cpp will cause a linker error.
*
* @tparam Table type to fetch
* @return A pointer to the requested table.
*/
template<typename T>
typename T::StorageType& GetEntriesMutable();
};


// These are included after the CDClientManager namespace declaration as CDTable as of Jan 29 2024 relies on CDClientManager in Templated code.
#include "CDTable.h"

#include "Singleton.h"

template<typename T>
T* CDClientManager::GetTable() {
return &T::Instance();
};

#endif //!__CDCLIENTMANAGER__H__
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "CDActivitiesTable.h"


void CDActivitiesTable::LoadValuesFromDatabase() {
// First, get the size of the table
uint32_t size = 0;
Expand All @@ -13,7 +14,8 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
tableSize.finalize();

// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);

// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Activities");
Expand All @@ -39,7 +41,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {
entry.noTeamLootOnDeath = tableData.getIntField("noTeamLootOnDeath", -1);
entry.optionalPercentage = tableData.getFloatField("optionalPercentage", -1.0f);

this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}

Expand All @@ -48,7 +50,7 @@ void CDActivitiesTable::LoadValuesFromDatabase() {

std::vector<CDActivities> CDActivitiesTable::Query(std::function<bool(CDActivities)> predicate) {

std::vector<CDActivities> data = cpplinq::from(this->entries)
std::vector<CDActivities> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@ struct CDActivities {
float optionalPercentage;
};

class CDActivitiesTable : public CDTable<CDActivitiesTable> {
private:
std::vector<CDActivities> entries;

class CDActivitiesTable : public CDTable<CDActivitiesTable, std::vector<CDActivities>> {
public:
void LoadValuesFromDatabase();

// Queries the table with a custom "where" clause
std::vector<CDActivities> Query(std::function<bool(CDActivities)> predicate);

const std::vector<CDActivities>& GetEntries() const { return this->entries; }
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "CDActivityRewardsTable.h"


void CDActivityRewardsTable::LoadValuesFromDatabase() {

// First, get the size of the table
Expand All @@ -14,7 +15,8 @@ void CDActivityRewardsTable::LoadValuesFromDatabase() {
tableSize.finalize();

// Reserve the size
this->entries.reserve(size);
auto& entries = GetEntriesMutable();
entries.reserve(size);

// Now get the data
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM ActivityRewards");
Expand All @@ -28,7 +30,7 @@ void CDActivityRewardsTable::LoadValuesFromDatabase() {
entry.ChallengeRating = tableData.getIntField("ChallengeRating", -1);
entry.description = tableData.getStringField("description", "");

this->entries.push_back(entry);
entries.push_back(entry);
tableData.nextRow();
}

Expand All @@ -37,7 +39,7 @@ void CDActivityRewardsTable::LoadValuesFromDatabase() {

std::vector<CDActivityRewards> CDActivityRewardsTable::Query(std::function<bool(CDActivityRewards)> predicate) {

std::vector<CDActivityRewards> data = cpplinq::from(this->entries)
std::vector<CDActivityRewards> data = cpplinq::from(GetEntries())
>> cpplinq::where(predicate)
>> cpplinq::to_vector();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,9 @@ struct CDActivityRewards {
std::string description; //!< The description
};

class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable> {
private:
std::vector<CDActivityRewards> entries;

class CDActivityRewardsTable : public CDTable<CDActivityRewardsTable, std::vector<CDActivityRewards>> {
public:
void LoadValuesFromDatabase();
// Queries the table with a custom "where" clause
std::vector<CDActivityRewards> Query(std::function<bool(CDActivityRewards)> predicate);

std::vector<CDActivityRewards> GetEntries() const;

};
31 changes: 18 additions & 13 deletions dDatabase/CDClientDatabase/CDClientTables/CDAnimationsTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

void CDAnimationsTable::LoadValuesFromDatabase() {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM Animations");
auto& animations = GetEntriesMutable();
while (!tableData.eof()) {
std::string animation_type = tableData.getStringField("animation_type", "");
DluAssert(!animation_type.empty());
Expand All @@ -24,7 +25,7 @@ void CDAnimationsTable::LoadValuesFromDatabase() {
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)

this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
}

Expand All @@ -35,6 +36,7 @@ bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) {
auto tableData = queryToCache.execQuery();
// If we received a bad lookup, cache it anyways so we do not run the query again.
if (tableData.eof()) return false;
auto& animations = GetEntriesMutable();

do {
std::string animation_type = tableData.getStringField("animation_type", "");
Expand All @@ -55,7 +57,7 @@ bool CDAnimationsTable::CacheData(CppSQLite3Statement& queryToCache) {
UNUSED_COLUMN(entry.priority = tableData.getFloatField("priority", 0.0f);)
UNUSED_COLUMN(entry.blendTime = tableData.getFloatField("blendTime", 0.0f);)

this->animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
animations[CDAnimationKey(animation_type, animationGroupID)].push_back(entry);
tableData.nextRow();
} while (!tableData.eof());

Expand All @@ -68,15 +70,17 @@ void CDAnimationsTable::CacheAnimations(const CDAnimationKey animationKey) {
auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM Animations WHERE animationGroupID = ? and animation_type = ?");
query.bind(1, static_cast<int32_t>(animationKey.second));
query.bind(2, animationKey.first.c_str());
auto& animations = GetEntriesMutable();
// If we received a bad lookup, cache it anyways so we do not run the query again.
if (!CacheData(query)) {
this->animations[animationKey];
animations[animationKey];
}
}

void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) {
auto animationEntryCached = this->animations.find(CDAnimationKey("", animationGroupID));
if (animationEntryCached != this->animations.end()) {
auto& animations = GetEntriesMutable();
auto animationEntryCached = animations.find(CDAnimationKey("", animationGroupID));
if (animationEntryCached != animations.end()) {
return;
}

Expand All @@ -85,28 +89,29 @@ void CDAnimationsTable::CacheAnimationGroup(AnimationGroupID animationGroupID) {

// Cache the query so we don't run the query again.
CacheData(query);
this->animations[CDAnimationKey("", animationGroupID)];
animations[CDAnimationKey("", animationGroupID)];
}

CDAnimationLookupResult CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) {
std::optional<CDAnimation> CDAnimationsTable::GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID) {
auto& animations = GetEntriesMutable();
CDAnimationKey animationKey(animationType, animationGroupID);
auto animationEntryCached = this->animations.find(animationKey);
if (animationEntryCached == this->animations.end()) {
auto animationEntryCached = animations.find(animationKey);
if (animationEntryCached == animations.end()) {
this->CacheAnimations(animationKey);
}

auto animationEntry = this->animations.find(animationKey);
auto animationEntry = animations.find(animationKey);
// If we have only one animation, return it regardless of the chance to play.
if (animationEntry->second.size() == 1) {
return CDAnimationLookupResult(animationEntry->second.front());
return animationEntry->second.front();
}
auto randomAnimation = GeneralUtils::GenerateRandomNumber<float>(0, 1);

for (auto& animationEntry : animationEntry->second) {
randomAnimation -= animationEntry.chance_to_play;
// This is how the client gets the random animation.
if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return CDAnimationLookupResult(animationEntry);
if (animationEntry.animation_name != previousAnimationName && randomAnimation <= 0.0f) return animationEntry;
}

return CDAnimationLookupResult();
return std::nullopt;
}
20 changes: 7 additions & 13 deletions dDatabase/CDClientDatabase/CDClientTables/CDAnimationsTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

#include "CDTable.h"
#include <list>
#include <optional>

typedef int32_t AnimationGroupID;
typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;

struct CDAnimation {
// uint32_t animationGroupID;
Expand All @@ -20,12 +25,7 @@ struct CDAnimation {
UNUSED_COLUMN(float blendTime;) //!< The blend time
};

typedef LookupResult<CDAnimation> CDAnimationLookupResult;

class CDAnimationsTable : public CDTable<CDAnimationsTable> {
typedef int32_t AnimationGroupID;
typedef std::string AnimationID;
typedef std::pair<std::string, AnimationGroupID> CDAnimationKey;
class CDAnimationsTable : public CDTable<CDAnimationsTable, std::map<CDAnimationKey, std::list<CDAnimation>>> {
public:
void LoadValuesFromDatabase();
/**
Expand All @@ -38,7 +38,7 @@ class CDAnimationsTable : public CDTable<CDAnimationsTable> {
* @param animationGroupID The animationGroupID to lookup
* @return CDAnimationLookupResult
*/
[[nodiscard]] CDAnimationLookupResult GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);
[[nodiscard]] std::optional<CDAnimation> GetAnimation(const AnimationID& animationType, const std::string& previousAnimationName, const AnimationGroupID animationGroupID);

/**
* Cache a full AnimationGroup by its ID.
Expand All @@ -58,10 +58,4 @@ class CDAnimationsTable : public CDTable<CDAnimationsTable> {
* @return false
*/
bool CacheData(CppSQLite3Statement& queryToCache);

/**
* Each animation is key'd by its animationName and its animationGroupID. Each
* animation has a possible list of animations. This is because there can be animations have a percent chance to play so one is selected at random.
*/
std::map<CDAnimationKey, std::list<CDAnimation>> animations;
};
Loading

0 comments on commit d2aeebc

Please sign in to comment.