1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-23 10:17:44 +00:00
sapphire/src/common/Exd/ExdData.h

117 lines
3 KiB
C
Raw Normal View History

#pragma once
2023-04-23 15:30:18 +02:00
#include <cstdint>
#include <memory>
2023-04-23 15:30:18 +02:00
#include <string>
#include <typeindex>
2023-04-23 15:30:18 +02:00
#include <unordered_map>
#include <vector>
#if !_WIN32
2023-04-23 15:30:18 +02:00
#include <cxxabi.h>
#endif
#include <Exd.h>
2023-04-23 15:30:18 +02:00
#include <ExdCat.h>
#include <ExdData.h>
#include <File.h>
#include <Logging/Logger.h>
2023-04-23 15:30:18 +02:00
#include <datReader/GameData.h>
namespace Sapphire::Data
{
class ExdData
{
public:
bool init( const std::string& path );
template< typename T >
2023-04-23 15:30:18 +02:00
std::shared_ptr< Excel::ExcelStruct< T > > getRow( uint32_t row, uint32_t subrow = 0 );
template< typename T >
2023-04-23 15:30:18 +02:00
std::vector< uint32_t > getIdList();
template< typename T >
2023-04-23 15:30:18 +02:00
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows();
std::shared_ptr< xiv::dat::GameData > getGameData()
{
return m_data;
}
private:
template< typename T >
2023-04-23 15:30:18 +02:00
std::string getSheetName();
2023-04-23 15:30:18 +02:00
template< typename T >
xiv::exd::Exd& getSheet();
std::unordered_map< std::type_index, xiv::exd::Exd > m_sheets;
std::shared_ptr< xiv::dat::GameData > m_data;
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
};
template< typename T >
2023-04-23 15:30:18 +02:00
std::string ExdData::getSheetName()
{
auto origName = std::string( typeid( T ).name() );
#if _WIN32
auto pos = origName.find_last_of( ':' );
return pos != std::string::npos ? origName.substr( pos + 1 ) : "[something_fucking_died]";
#else
int status = -4;
char* res = abi::__cxa_demangle( origName.c_str(), nullptr, nullptr, &status );
std::string demangledName = ( status == 0 ) ? res : origName;
auto pos = demangledName.find_last_of( ':' );
if( pos != std::string::npos ) demangledName = demangledName.substr( pos + 1 );
free( res );
return demangledName;
#endif
}
template< typename T >
xiv::exd::Exd& ExdData::getSheet()
{
auto needle = m_sheets.find( typeid( T ) );
if( needle == m_sheets.end() )
{
auto sheetName = getSheetName< T >();
auto& cat = m_exd_data->get_category( sheetName );
needle = m_sheets.emplace( typeid( T ), static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) ) ).first;
}
return needle->second;
}
template< typename T >
std::shared_ptr< Excel::ExcelStruct< T > > ExdData::getRow( uint32_t row, uint32_t subrow )
{
try
{
return getSheet< T >().template get_row< T >( row );
2023-04-23 15:30:18 +02:00
} catch( const std::runtime_error& ex )
{
Logger::error( "Error fetching row from sheet {}: {}", getSheetName< T >(), ex.what() );
return nullptr;
} catch( const std::out_of_range& )
{
return nullptr;
}
}
template< typename T >
std::vector< uint32_t > ExdData::getIdList()
{
auto sheet = getSheet< T >();
auto rows = sheet.get_rows();
std::vector< uint32_t > ids;
for( const auto& row : rows ) ids.push_back( row.first );
return ids;
}
template< typename T >
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > ExdData::getRows()
{
return getSheet< T >().template get_sheet_rows< T >();
2023-04-23 15:30:18 +02:00
}
2023-04-23 15:30:18 +02:00
}// namespace Sapphire::Data