PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Core/Asset/AssetClass.cpp

https://github.com/goofoo/Helium
C++ | 330 lines | 258 code | 56 blank | 16 comment | 51 complexity | ea422a41b6af3de29cd7bb3ce19dc488 MD5 | raw file
  1. #include "AssetClass.h"
  2. #include "Foundation/Log.h"
  3. #include "Foundation/Reflect/Object.h"
  4. #include "Foundation/Reflect/Version.h"
  5. #include "Foundation/Reflect/Visitor.h"
  6. #include "Foundation/Reflect/Serializers.h"
  7. #include "Foundation/Component/Component.h"
  8. #include "Core/Asset/Classes/Entity.h"
  9. #include "Core/Asset/Classes/ShaderAsset.h"
  10. #include "Core/Asset/Classes/SceneAsset.h"
  11. #include <memory>
  12. using namespace Helium;
  13. using namespace Helium::Reflect;
  14. using namespace Helium::Asset;
  15. const tchar* ASSET_VERSION = TXT( "1" );
  16. tstring AssetClass::s_BaseBuiltDirectory = TXT( "" );
  17. std::map< tstring, AssetFactory* > AssetClass::s_AssetFactories;
  18. REFLECT_DEFINE_ABSTRACT( AssetClass );
  19. void AssetClass::EnumerateClass( Reflect::Compositor<AssetClass>& comp )
  20. {
  21. comp.AddField( &AssetClass::m_Description, "m_Description" );
  22. comp.AddField( &AssetClass::m_Tags, "m_Tags" );
  23. comp.AddField( &AssetClass::m_Path, "m_Path", Reflect::FieldFlags::Hide );
  24. }
  25. AssetClass::AssetClass()
  26. {
  27. }
  28. AssetClassPtr AssetClass::LoadAssetClass( const tchar* path )
  29. {
  30. AssetClassPtr assetClass = NULL;
  31. try
  32. {
  33. Helium::Path filePath( path );
  34. assetClass = Reflect::Archive::FromFile< AssetClass >( filePath );
  35. assetClass->SetSerializationPath( filePath );
  36. assetClass->LoadFinished();
  37. }
  38. catch ( const Helium::Exception& exception )
  39. {
  40. Log::Warning( TXT( "%s\n" ), exception.What() );
  41. }
  42. // success
  43. return assetClass;
  44. }
  45. Helium::Path AssetClass::GetBuiltDirectory()
  46. {
  47. #pragma TODO( "make human-readable built directories" )
  48. tstringstream str;
  49. str << TUID_HEX_FORMAT << m_Path.Hash();
  50. Helium::Path builtDirectory( s_BaseBuiltDirectory + TXT( "/" ) + str.str() );
  51. return builtDirectory;
  52. }
  53. tstring AssetClass::GetFullName() const
  54. {
  55. return m_Path.Get();
  56. }
  57. tstring AssetClass::GetShortName() const
  58. {
  59. return m_Path.Basename();
  60. }
  61. void AssetClass::GatherSearchableProperties( Helium::SearchableProperties* properties ) const
  62. {
  63. properties->Insert( TXT( "AssetDescription" ), m_Description );
  64. for ( std::set< tstring >::const_iterator itr = m_Tags.begin(), end = m_Tags.end(); itr != end; ++itr )
  65. {
  66. properties->Insert( TXT( "AssetTag" ), (*itr) );
  67. }
  68. __super::GatherSearchableProperties( properties );
  69. }
  70. namespace Helium
  71. {
  72. namespace Asset
  73. {
  74. class AssetDependencyVisitor : public Reflect::Visitor
  75. {
  76. public:
  77. std::set< Helium::Path >& m_Dependencies;
  78. AssetDependencyVisitor(std::set< Helium::Path >& dependencies)
  79. : m_Dependencies( dependencies )
  80. {
  81. }
  82. virtual ~AssetDependencyVisitor()
  83. {
  84. }
  85. virtual bool VisitField(Element* element, const Field* field) HELIUM_OVERRIDE
  86. {
  87. if ( field->m_SerializerID == Reflect::GetType< Reflect::PathSerializer >() )
  88. {
  89. Helium::Path path;
  90. if ( Reflect::Serializer::GetValue( field->CreateSerializer( element ), path ) )
  91. {
  92. m_Dependencies.insert( path );
  93. return false;
  94. }
  95. }
  96. //-----------------------------------------------
  97. else if ( field->m_SerializerID == Reflect::GetType< Reflect::ArraySerializer >() )
  98. {
  99. const Reflect::ArraySerializer* arraySerializer = Reflect::ConstDangerousCast<Reflect::ArraySerializer>( field->CreateSerializer( element ) );
  100. if ( arraySerializer->GetItemType() == Reflect::GetType< Reflect::PathSerializer >() )
  101. {
  102. if ( (int)arraySerializer->GetSize() < 1 )
  103. {
  104. return true;
  105. }
  106. for ( size_t index = 0; index < arraySerializer->GetSize(); ++index )
  107. {
  108. Helium::Path path;
  109. if ( Reflect::Serializer::GetValue( arraySerializer->GetItem( index ), path ) )
  110. {
  111. m_Dependencies.insert( path );
  112. }
  113. }
  114. return false;
  115. }
  116. }
  117. //-----------------------------------------------
  118. else if ( field->m_SerializerID == Reflect::GetType< Reflect::MapSerializer >() )
  119. {
  120. const Reflect::MapSerializer* mapSerializer = Reflect::ConstDangerousCast<Reflect::MapSerializer>( field->CreateSerializer( element ) );
  121. if ( mapSerializer->GetValueType() == Reflect::GetType< Reflect::PathSerializer >() )
  122. {
  123. if ( (int)mapSerializer->GetSize() < 1 )
  124. {
  125. return true;
  126. }
  127. Reflect::MapSerializer::V_ConstValueType data;
  128. mapSerializer->GetItems( data );
  129. Reflect::MapSerializer::V_ConstValueType::const_iterator itr = data.begin();
  130. Reflect::MapSerializer::V_ConstValueType::const_iterator end = data.end();
  131. for ( ; itr != end; ++itr )
  132. {
  133. Helium::Path path;
  134. if ( Reflect::Serializer::GetValue( itr->second, path ) )
  135. {
  136. m_Dependencies.insert( path );
  137. }
  138. }
  139. return false;
  140. }
  141. }
  142. //-----------------------------------------------
  143. else if ( field->m_SerializerID == Reflect::GetType< Reflect::SetSerializer >() )
  144. {
  145. const Reflect::SetSerializer* setSerializer = Reflect::ConstDangerousCast<Reflect::SetSerializer>( field->CreateSerializer( element ) );
  146. if ( setSerializer->GetItemType() == Reflect::GetType< Reflect::PathSerializer >() )
  147. {
  148. if ( (int)setSerializer->GetSize() < 1 )
  149. {
  150. return true;
  151. }
  152. Reflect::V_ConstSerializer data;
  153. setSerializer->GetItems( data );
  154. Reflect::V_ConstSerializer::const_iterator itr = data.begin();
  155. Reflect::V_ConstSerializer::const_iterator end = data.end();
  156. for ( ; itr != end; ++itr )
  157. {
  158. Helium::Path path;
  159. if ( Reflect::Serializer::GetValue( (*itr), path ) )
  160. {
  161. m_Dependencies.insert( path );
  162. }
  163. }
  164. return false;
  165. }
  166. }
  167. //-----------------------------------------------
  168. else if ( field->m_SerializerID == Reflect::GetType< Reflect::ElementArraySerializer >() )
  169. {
  170. const Reflect::ElementArraySerializer* arraySerializer = Reflect::ConstDangerousCast< Reflect::ElementArraySerializer >( field->CreateSerializer( element ) );
  171. if ( (int)arraySerializer->GetSize() < 1 )
  172. {
  173. return true;
  174. }
  175. const Reflect::V_Element& vals = arraySerializer->m_Data.Ref();
  176. for ( Reflect::V_Element::const_iterator itr = vals.begin(), end = vals.end(); itr != end; ++itr )
  177. {
  178. (*itr)->Host( *this );
  179. }
  180. return false;
  181. }
  182. //-----------------------------------------------
  183. else if ( field->m_SerializerID == Reflect::GetType< Reflect::ElementMapSerializer >() )
  184. {
  185. const Reflect::ElementMapSerializer* mapSerializer = Reflect::ConstDangerousCast< Reflect::ElementMapSerializer >( field->CreateSerializer( element ) );
  186. if ( (int)mapSerializer->GetSize() < 1 )
  187. {
  188. return true;
  189. }
  190. Reflect::ElementMapSerializer::V_ConstValueType data;
  191. mapSerializer->GetItems( data );
  192. Reflect::ElementMapSerializer::V_ConstValueType::const_iterator itr = data.begin();
  193. Reflect::ElementMapSerializer::V_ConstValueType::const_iterator end = data.end();
  194. for ( ; itr != end; ++itr )
  195. {
  196. (*itr->second)->Host( *this );
  197. }
  198. return false;
  199. }
  200. //-----------------------------------------------
  201. else if ( field->m_SerializerID == Reflect::GetType< Reflect::ElementSetSerializer >() )
  202. {
  203. const Reflect::ElementSetSerializer* setSerializer = Reflect::ConstDangerousCast< Reflect::ElementSetSerializer >( field->CreateSerializer( element ) );
  204. if ( (int)setSerializer->GetSize() < 1 )
  205. {
  206. return true;
  207. }
  208. const Reflect::ElementSetSerializer::DataType& vals = setSerializer->m_Data.Ref();
  209. for ( Reflect::ElementSetSerializer::DataType::const_iterator itr = vals.begin(), end = vals.end(); itr != end; ++itr )
  210. {
  211. (*itr)->Host( *this );
  212. }
  213. return false;
  214. }
  215. // continue search
  216. return true;
  217. }
  218. };
  219. }
  220. }
  221. void AssetClass::GetFileReferences( std::set< Helium::Path >& fileReferences )
  222. {
  223. AssetDependencyVisitor assetDepVisitor( fileReferences );
  224. this->Host( assetDepVisitor );
  225. //__super::GetFileReferences( fileReferences );
  226. fileReferences.erase( m_Path );
  227. }
  228. void AssetClass::ComponentChanged( const Component::ComponentBase* component )
  229. {
  230. __super::ComponentChanged( component );
  231. }
  232. bool AssetClass::SetComponent( const Component::ComponentPtr& component, bool validate, tstring* error )
  233. {
  234. return __super::SetComponent( component, validate, error );
  235. }
  236. bool AssetClass::RemoveComponent( i32 typeID )
  237. {
  238. return __super::RemoveComponent( typeID );
  239. }
  240. void AssetClass::Serialize()
  241. {
  242. Reflect::Version version( TXT( "Pipeline" ), ASSET_VERSION );
  243. Reflect::Archive::ToFile( this, m_Path, &version );
  244. m_Modified = false;
  245. }
  246. /////////////////////////////////////////////////////////////////////////////
  247. // Override this function to provide logic that makes sure an asset class is
  248. // valid. Fill out the error message provided so that it can be reported
  249. // to the user. This function is intended to be used by the UI to make sure
  250. // that an asset is valid before it is built (validation is done during save).
  251. //
  252. bool AssetClass::ValidateClass( tstring& error ) const
  253. {
  254. error.clear();
  255. return true;
  256. }
  257. bool AssetClass::ValidateCompatible( const Component::ComponentPtr &component, tstring& error ) const
  258. {
  259. if ( component->GetComponentUsage() == Component::ComponentUsages::Instance )
  260. {
  261. error = TXT( "The " ) + component->GetClass()->m_UIName + TXT( " component can only be added to an instance of an asset." );
  262. return false;
  263. }
  264. return __super::ValidateCompatible( component, error );
  265. }
  266. void AssetClass::LoadFinished()
  267. {
  268. }
  269. void AssetClass::CopyTo(const Reflect::ElementPtr& destination)
  270. {
  271. // Restore the Asset Class ID after performing the copy
  272. AssetClass* destinationAsset = Reflect::ObjectCast< AssetClass >( destination );
  273. __super::CopyTo( destination );
  274. }