@ -9,10 +9,11 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "content_manager.h"
# include "content_manager.h"
# include <editor/editor.h>
# include <core/common_defs.h>
# include "../project.h"
# include <pugixml.hpp>
# include "editor_asset.h"
# include "editor_asset.h"
# include "../project.h"
# include <editor/editor.h>
# include <fstream>
// Asset types
// Asset types
# include "tile_set.h"
# include "tile_set.h"
@ -52,7 +53,7 @@ namespace lunarium { namespace editor
mpProject = project ;
mpProject = project ;
std : : filesystem : : path root = mpProject - > GetRootDirectory ( ) ;
std : : filesystem : : path root = mpProject - > GetRootDirectory ( ) ;
mContentFile = root / " contents/content_meta. xml " ;
mContentFile = root / " contents/content_meta. json " ;
// If this is a new project being generated just create a base contents file
// If this is a new project being generated just create a base contents file
if ( ! std : : filesystem : : exists ( mContentFile ) )
if ( ! std : : filesystem : : exists ( mContentFile ) )
@ -72,72 +73,93 @@ namespace lunarium { namespace editor
return Save ( ) ;
return Save ( ) ;
}
}
// Load the file
std : : ifstream ifs = std : : ifstream ( mContentFile . string ( ) . c_str ( ) ) ;
pugi : : xml_document doc ;
if ( ! ifs . is_open ( ) )
pugi : : xml_parse_result result = doc . load_file ( mContentFile . string ( ) . c_str ( ) ) ;
if ( result . status ! = pugi : : xml_parse_status : : status_ok )
{
{
return OpRes : : Fail ( " Could not open contents file: %s , %s " , mContentFile . string ( ) . c_str ( ) , result . description ( ) ) ;
return OpRes : : Fail ( " Could not open contents file: %s " , mContentFile . string ( ) . c_str ( ) ) ;
}
}
pugi : : xml_node proj_node = doc . child ( " Project " ) ;
nlohmann : : json j ;
if ( ! proj_node )
ifs > > j ;
ifs . close ( ) ;
auto p = j [ " Project " ] ;
if ( p . is_null ( ) )
{
{
return OpRes : : Fail ( " content_meta.xml missing Project root node " ) ;
return OpRes : : Fail ( " content_meta. json missing Project element " ) ;
}
}
// Get ID
if ( p [ " NextID " ] . is_null ( ) )
pugi : : xml_node ID = proj_node . child ( " NextID " ) ;
if ( ! ID )
{
{
return OpRes : : Fail ( " content_meta.xml missing NextID node " ) ;
return OpRes : : Fail ( " content_meta.xml missing NextID node " ) ;
}
}
mNextID = ID. attribute ( " ID " ) . as_ullong ( ) ;
mNextID = p[ " NextID " ] . get < u64 > ( ) ;
pugi : : xml_node contents = proj_node . child ( " Contents " ) ;
auto c = p [ " Contents " ] ;
if ( ! contents )
if ( c . is_null ( ) )
{
{
return OpRes : : Fail ( " content_meta.xml missing Contents node " ) ;
return OpRes : : Fail ( " content_meta.xml missing Contents node " ) ;
}
}
// Iterate through content
// ARRAY EXAMPLE
for ( pugi : : xml_node asset = contents . child ( " Asset " ) ; asset ; asset = asset . next_sibling ( " Asset " ) )
/*
std : : string raw = " { \" Contents \" : [ { \" Name \" : \" first \" , \" ID \" : 1 }, { \" Name \" : \" second \" , \" ID \" : 2 }]} " ;
auto j = nlohmann : : json : : parse ( raw ) ;
for ( auto it = j [ " Contents " ] . begin ( ) ; it ! = j [ " Contents " ] . end ( ) ; + + it )
{
std : : cout < < ( * it ) [ " ID " ] < < " - " < < ( * it ) [ " Name " ] < < " \n " ;
}
nlohmann : : json oj ;
oj [ " Contents " ] . push_back ( { { " Name " , " first " } , { " ID " , 1 } } ) ;
oj [ " Contents " ] . push_back ( { { " Name " , " second " } , { " ID " , 2 } } ) ;
std : : cout < < " \n " < < std : : setw ( 4 ) < < oj ;
*/
///////////////////////////////////
for ( auto it = c . begin ( ) ; it ! = c . end ( ) ; + + it )
{
{
auto & asset = ( * it ) ;
if ( ! IsValidAsset ( asset ) )
if ( ! IsValidAsset ( asset ) )
{
{
return OpRes : : Fail ( " Invalid asset node in content_meta.xml " ) ;
return OpRes : : Fail ( " Invalid asset node in content_meta. json " ) ;
}
}
// Load Type
// Load Type
AssetType type = ( AssetType ) asset . attribute ( " Type " ) . as_int ( ) ;
AssetType type = ( AssetType ) asset [" Type " ] . get < int > ( ) ;
EditorAsset * pAsset = CreateAsset ( type ) ;
EditorAsset * pAsset = CreateAsset ( type ) ;
pAsset - > mAssetDir = mpProject - > GetAssetDirectory ( ) ;
if ( ! pAsset )
if ( ! pAsset )
{
{
return OpRes : : Fail ( " Could not create Editor Asset. Unknown type: %n " , ( int ) type ) ;
return OpRes : : Fail ( " Could not create Editor Asset. Unknown type: %n " , ( int ) type ) ;
}
}
pAsset - > mAssetDir = mpProject - > GetAssetDirectory ( ) ;
// Load ID
// Load ID
pAsset - > mID = ( uint64_t ) asset . attribute ( " ID " ) . as_ullong ( ) ;
pAsset - > mID = asset [ " ID " ] . get < u64 > ( ) ;
// Load Location
// Load Location
pAsset - > mLocation = std : : filesystem : : path ( asset .attribute ( " Location " ) . as_string ( ) ) ;
pAsset - > mLocation = std : : filesystem : : path ( asset [" Location " ] . get < std : : string > ( ) ) ;
// Load type specific data
// Load type specific data
if ( Failed ( pAsset - > LoadFrom XML( asse t) . LogIfFailed ( Editor : : LogCat ) ) )
if ( Failed ( pAsset - > LoadFrom JSON( asset ) . LogIfFailed ( Editor : : LogCa t) . LogIfFailed ( Editor : : LogCat ) ) )
{
{
return OpRes : : Fail ( " Could not load asset type specific data for asset with ID: %llu, File: %s " ,
return OpRes : : Fail ( " Could not load asset type specific data for asset with ID: %llu, File: %s " ,
pAsset - > GetID ( ) , pAsset - > GetFileLocation ( ) . filename ( ) . string ( ) . c_str ( ) ) ;
pAsset - > GetID ( ) , pAsset - > GetFileLocation ( ) . filename ( ) . string ( ) . c_str ( ) ) ;
}
}
// Store asset
// Store asset
if ( mAssets . find ( pAsset - > mID ) ! = mAssets . end ( ) )
auto iter = mAssets . find ( pAsset - > mID ) ;
if ( iter ! = mAssets . end ( ) )
{
{
return OpRes : : Fail ( " Asset ID collision, ID: %llu, File: %s " ,
return OpRes : : Fail ( " Asset ID collision, First asset: ID: %llu, File: %s, Second asset: ID: %llu, File: %s " ,
iter - > second - > GetID ( ) , iter - > second - > GetFileLocation ( ) . filename ( ) . string ( ) . c_str ( ) ,
pAsset - > GetID ( ) , pAsset - > GetFileLocation ( ) . filename ( ) . string ( ) . c_str ( ) ) ;
pAsset - > GetID ( ) , pAsset - > GetFileLocation ( ) . filename ( ) . string ( ) . c_str ( ) ) ;
}
}
@ -154,35 +176,43 @@ namespace lunarium { namespace editor
return OpRes : : Fail ( " ConentManager::Save failed: no project set " ) ;
return OpRes : : Fail ( " ConentManager::Save failed: no project set " ) ;
}
}
nlohmann : : json oj ;
auto & p = oj [ " Project " ] ;
// Save header info
// Save header info
pugi : : xml_document doc ;
p [ " Name " ] = mpProject - > GetName ( ) ;
pugi : : xml_node proj_node = doc . append_child ( " Project " ) ;
p [ " NextID " ] = mNextID ;
proj_node . append_attribute ( " Name " ) . set_value ( mpProject - > GetName ( ) . c_str ( ) ) ;
proj_node . append_child ( " NextID " ) . append_attribute ( " ID " ) . set_value ( mNextID ) ;
// pugi::xml_node proj_node = doc.append_child("Contents");
// Save all assets
// Save all assets
pugi : : xml_node contents = proj_node . append_child ( " Contents " ) ;
auto & c = p [ " Contents " ] ;
for ( auto iter = mAssets . begin ( ) ; iter ! = mAssets . end ( ) ; iter + + )
for ( auto iter = mAssets . begin ( ) ; iter ! = mAssets . end ( ) ; iter + + )
{
{
EditorAsset * pAsset = iter - > second ;
EditorAsset * pAsset = iter - > second ;
pugi: : xml_node asset = contents . append_child ( " Asset " ) ;
nlohmann: : json asset ;
asset . append_attribute ( " Type " ) . set_value ( ( int ) pAsset - > GetType ( ) ) ;
asset [ " Type " ] = ( i32 ) pAsset - > GetType ( ) ;
asset . append_attribute ( " ID " ) . set_value ( pAsset - > GetID ( ) ) ;
asset [ " ID " ] = pAsset - > GetID ( ) ;
asset . append_attribute ( " Location " ) . set_value ( pAsset - > GetFileLocation ( ) . string ( ) . c_str ( ) ) ;
if ( Failed ( pAsset - > SaveToXML ( asset ) . LogIfFailed ( Editor : : LogCat ) ) )
// TODO: This needs to be a relative path! (Relative to the project root)
asset [ " Location " ] = pAsset - > GetFileLocation ( ) . string ( ) . c_str ( ) ;
if ( Failed ( pAsset - > SaveToJSON ( asset ) . LogIfFailed ( Editor : : LogCat ) . LogIfFailed ( Editor : : LogCat ) ) )
{
{
return OpRes : : Fail ( " Could not save asset meta data for file: %s " , pAsset - > GetFileLocation ( ) . string ( ) . c_str ( ) ) ;
return OpRes : : Fail ( " Could not save asset meta data for file: %s " , pAsset - > GetFileLocation ( ) . string ( ) . c_str ( ) ) ;
}
}
c . push_back ( asset ) ;
}
}
if ( ! doc . save_file ( mContentFile . string ( ) . c_str ( ) ) )
std : : ofstream ofs = std : : ofstream ( mContentFile . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
{
return OpRes : : Fail ( " ContentManager could not save file: %s " , mContentFile . string ( ) . c_str ( ) ) ;
return OpRes : : Fail ( " ContentManager could not save file: %s - could not open file " , mContentFile . string ( ) . c_str ( ) ) ;
}
}
ofs < < std : : setw ( 4 ) < < oj ;
ofs . close ( ) ;
return OpRes : : OK ( ) ;
return OpRes : : OK ( ) ;
}
}
@ -254,11 +284,13 @@ namespace lunarium { namespace editor
return OpRes : : Fail ( " Could not copy asset file from: %s to: %s " , file . string ( ) . c_str ( ) , to_location . string ( ) . c_str ( ) ) ;
return OpRes : : Fail ( " Could not copy asset file from: %s to: %s " , file . string ( ) . c_str ( ) , to_location . string ( ) . c_str ( ) ) ;
}
}
EditorAsset * pAsset = CreateAsset ( type ) ;
EditorAsset * pAsset = CreateAsset ( type ) ;
pAsset - > mAssetDir = mpProject - > GetAssetDirectory ( ) ;
pAsset - > mAssetDir = mpProject - > GetAssetDirectory ( ) ;
pAsset - > mID = mNextID ;
pAsset - > mID = mNextID ;
mNextID + + ;
mNextID + + ;
pAsset - > mLocation = to_location;
pAsset - > mLocation = mpProject- > MakeRelativeToRoot ( to_location) ;
if ( Failed ( pAsset - > LoadRawFile ( ) . LogIfFailed ( Editor : : LogCat ) ) )
if ( Failed ( pAsset - > LoadRawFile ( ) . LogIfFailed ( Editor : : LogCat ) ) )
{
{
delete pAsset ;
delete pAsset ;
@ -283,11 +315,14 @@ namespace lunarium { namespace editor
mAssets . erase ( iter ) ;
mAssets . erase ( iter ) ;
}
}
bool ContentManager : : IsValidAsset ( pugi: : xml_node & node )
bool ContentManager : : IsValidAsset ( nlohmann: : json & node )
{
{
if ( ! node . attribute ( " ID " ) ) { return false ; }
if ( node . is_null ( ) ) { return false ; }
if ( ! node . attribute ( " Type " ) ) { return false ; }
if ( node [ " ID " ] . is_null ( ) ) { return false ; }
if ( ! node . attribute ( " Location " ) ) { return false ; }
if ( ! node [ " ID " ] . is_number_unsigned ( ) ) { return false ; }
if ( node [ " Type " ] . is_null ( ) ) { return false ; }
if ( ! node [ " Type " ] . is_number ( ) ) { return false ; }
if ( node [ " Location " ] . is_null ( ) ) { return false ; }
return true ;
return true ;
}
}