2021-11-27 00:53:57 +01:00
|
|
|
#pragma once
|
|
|
|
|
2023-04-23 15:30:18 +02:00
|
|
|
#include <cstdint>
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <memory>
|
2023-04-23 15:30:18 +02:00
|
|
|
#include <string>
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <typeindex>
|
2023-04-23 15:30:18 +02:00
|
|
|
#include <unordered_map>
|
|
|
|
#include <vector>
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
#if !_WIN32
|
2023-04-23 15:30:18 +02:00
|
|
|
#include <cxxabi.h>
|
2021-11-27 00:53:57 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <Exd.h>
|
2023-04-23 15:30:18 +02:00
|
|
|
#include <ExdCat.h>
|
|
|
|
#include <ExdData.h>
|
|
|
|
#include <File.h>
|
2021-11-27 00:53:57 +01:00
|
|
|
#include <Logging/Logger.h>
|
2023-04-23 15:30:18 +02:00
|
|
|
#include <datReader/GameData.h>
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
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 );
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
template< typename T >
|
2023-04-23 15:30:18 +02:00
|
|
|
std::vector< uint32_t > getIdList();
|
2021-11-27 00:53:57 +01:00
|
|
|
|
2023-03-24 17:38:58 -03:00
|
|
|
template< typename T >
|
2023-04-23 15:30:18 +02:00
|
|
|
std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows();
|
2023-03-24 17:38:58 -03:00
|
|
|
|
2023-04-23 17:51:20 +02:00
|
|
|
std::shared_ptr< xiv::dat::GameData > getGameData()
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
return m_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
template< typename T >
|
2023-04-23 15:30:18 +02:00
|
|
|
std::string getSheetName();
|
2021-11-27 00:53:57 +01:00
|
|
|
|
2023-04-23 15:30:18 +02:00
|
|
|
template< typename T >
|
|
|
|
xiv::exd::Exd& getSheet();
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
std::unordered_map< std::type_index, xiv::exd::Exd > m_sheets;
|
2023-04-24 10:21:14 +02:00
|
|
|
std::unordered_map< std::type_index, std::string > m_name_cache;
|
2021-11-27 00:53:57 +01:00
|
|
|
std::shared_ptr< xiv::dat::GameData > m_data;
|
|
|
|
std::shared_ptr< xiv::exd::ExdData > m_exd_data;
|
|
|
|
};
|
|
|
|
|
2023-04-23 20:03:19 +02:00
|
|
|
template< typename T >
|
2023-04-23 15:30:18 +02:00
|
|
|
std::string ExdData::getSheetName()
|
|
|
|
{
|
2023-04-24 10:21:14 +02:00
|
|
|
auto type = std::type_index( typeid( T ) );
|
|
|
|
auto it = m_name_cache.find( type );
|
|
|
|
if( it != m_name_cache.end() )
|
|
|
|
{
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
2023-04-23 15:30:18 +02:00
|
|
|
auto origName = std::string( typeid( T ).name() );
|
2023-04-23 20:03:19 +02:00
|
|
|
|
2023-04-23 15:30:18 +02:00
|
|
|
#if _WIN32
|
|
|
|
auto pos = origName.find_last_of( ':' );
|
2023-04-23 20:03:19 +02:00
|
|
|
if( pos != std::string::npos )
|
|
|
|
{
|
2023-04-24 10:21:14 +02:00
|
|
|
std::string sheetName = origName.substr( pos + 1 );
|
|
|
|
m_name_cache[ type ] = sheetName;
|
|
|
|
return sheetName;
|
2023-04-23 20:03:19 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw std::runtime_error( "Failed to extract the sheet name" );
|
|
|
|
}
|
2023-04-23 15:30:18 +02:00
|
|
|
#else
|
|
|
|
int status = -4;
|
|
|
|
char* res = abi::__cxa_demangle( origName.c_str(), nullptr, nullptr, &status );
|
2023-04-23 20:03:19 +02:00
|
|
|
if( status == 0 )
|
|
|
|
{
|
|
|
|
std::string demangledName = res;
|
|
|
|
auto pos = demangledName.find_last_of( ':' );
|
|
|
|
if( pos != std::string::npos ) demangledName = demangledName.substr( pos + 1 );
|
2023-04-24 10:21:14 +02:00
|
|
|
m_name_cache[ type ] = demangledName;
|
2023-04-23 20:03:19 +02:00
|
|
|
free( res );
|
|
|
|
return demangledName;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw std::runtime_error( "Failed to demangle the type name" );
|
|
|
|
}
|
2023-04-23 15:30:18 +02:00
|
|
|
#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
|
|
|
|
{
|
2023-04-23 17:51:20 +02:00
|
|
|
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()
|
|
|
|
{
|
2023-04-23 17:51:20 +02:00
|
|
|
return getSheet< T >().template get_sheet_rows< T >();
|
2023-04-23 15:30:18 +02:00
|
|
|
}
|
2021-11-27 00:53:57 +01:00
|
|
|
|
2023-04-23 15:30:18 +02:00
|
|
|
}// namespace Sapphire::Data
|