yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
0d16228ae
master
1// slang-artifact-impl.cpp 2#include "slang-artifact-impl.h" 3 4#include "../core/slang-castable.h" 5#include "slang-artifact-desc-util.h" 6#include "slang-artifact-handler-impl.h" 7#include "slang-artifact-representation.h" 8#include "slang-artifact-util.h" 9#include "slang-slice-allocator.h" 10 11namespace Slang 12{ 13 14namespace 15{// anonymous 16 17/* Get a view as a slice of *raw* pointers */ 18template < typename T > 19SLANG_FORCE_INLINE ConstArrayView < T *> _getRawView (const List < ComPtr < T >>& in ) 20{ 21return makeConstArrayView ((T * const * )in .getBuffer (),in .getCount ()); 22} 23 24}// namespace 25 26/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Artifact !!!!!!!!!!!!!!!!!!!!!!!!!!! */ 27 28void * Artifact ::castAs (const Guid & guid ) 29{ 30if (auto ptr = getInterface (guid )) 31 { 32return ptr ; 33 } 34return getObject (guid ); 35} 36 37void * Artifact ::getInterface (const Guid & uuid ) 38{ 39if (uuid == ISlangUnknown ::getTypeGuid ()|| uuid == ICastable ::getTypeGuid ()|| 40uuid == IArtifact ::getTypeGuid ()) 41 { 42return static_cast < IArtifact *> (this ); 43 } 44return nullptr ; 45} 46 47void * Artifact ::getObject (const Guid & uuid ) 48{ 49SLANG_UNUSED (uuid ); 50return nullptr ; 51} 52 53IArtifactHandler * Artifact ::_getHandler () 54{ 55return m_handler ?m_handler :DefaultArtifactHandler ::getSingleton (); 56} 57 58void Artifact ::_requireChildren () 59{ 60if (m_expandResult == SLANG_E_UNINITIALIZED ) 61 { 62const auto res = expandChildren (); 63SLANG_UNUSED (res ); 64 65SLANG_ASSERT (SLANG_SUCCEEDED (res )|| res == SLANG_E_NOT_IMPLEMENTED ); 66 } 67} 68 69bool Artifact ::exists () 70{ 71for (ICastable * rep :m_representations .getArrayView ()) 72 { 73if (auto artifactRep = as < IArtifactRepresentation > (rep )) 74 { 75// It is an artifact rep and it exists, we are done 76if (artifactRep -> exists ()) 77 { 78return true; 79 } 80 } 81else 82 { 83// If it's *not* IArtifactRepresentation derived, it's existance *is* a representation 84return true; 85 } 86 } 87 88return false; 89} 90 91SlangResult Artifact ::requireFile (Keep keep ,IOSFileArtifactRepresentation ** outFileRep ) 92{ 93auto handler = _getHandler (); 94 95ComPtr < ICastable > castable ; 96SLANG_RETURN_ON_FAIL (handler -> getOrCreateRepresentation ( 97this , 98IOSFileArtifactRepresentation ::getTypeGuid (), 99keep , 100castable .writeRef ())); 101 102auto fileRep = as < IOSFileArtifactRepresentation > (castable ); 103fileRep -> addRef (); 104 105* outFileRep = fileRep ; 106return SLANG_OK ; 107} 108 109SlangResult Artifact ::loadSharedLibrary (ArtifactKeep keep ,ISlangSharedLibrary ** outSharedLibrary ) 110{ 111auto handler = _getHandler (); 112 113ComPtr < ICastable > castable ; 114SLANG_RETURN_ON_FAIL (handler -> getOrCreateRepresentation ( 115this , 116ISlangSharedLibrary ::getTypeGuid (), 117keep , 118castable .writeRef ())); 119 120auto lib = as < ISlangSharedLibrary > (castable ); 121lib -> addRef (); 122 123* outSharedLibrary = lib ; 124return SLANG_OK ; 125} 126 127IArtifactHandler * Artifact ::getHandler () 128{ 129return m_handler ; 130} 131 132void Artifact ::setHandler (IArtifactHandler * handler ) 133{ 134m_handler = handler ; 135} 136 137void Artifact ::clear (IArtifact ::ContainedKind kind ) 138{ 139switch (kind ) 140 { 141case ContainedKind ::Associated : 142m_associated .clear (); 143break ; 144case ContainedKind ::Representation : 145m_representations .clear (); 146break ; 147case ContainedKind ::Children : 148m_children .clear (); 149break ; 150default : 151break ; 152 } 153} 154 155void Artifact ::removeAt (ContainedKind kind ,Index i ) 156{ 157switch (kind ) 158 { 159case ContainedKind ::Associated : 160m_associated .removeAt (i ); 161break ; 162case ContainedKind ::Representation : 163m_representations .removeAt (i ); 164break ; 165case ContainedKind ::Children : 166m_children .removeAt (i ); 167break ; 168default : 169break ; 170 } 171} 172 173uint32_t Artifact ::getItemCount () 174{ 175// Ignore the metadata when counting items, and the base artifact is item 0. 176uint32_t count = 1 ; 177for (auto artifact :m_associated ) 178if (artifact -> getDesc ().payload != ArtifactPayload ::Metadata && 179artifact -> getDesc ().payload != ArtifactPayload ::PostEmitMetadata ) 180count ++ ; 181return count ; 182} 183 184SlangResult Artifact ::getItemData (uint32_t index , slang::IBlob ** outblob ) 185{ 186// Item 0 is the base artifact, otherwise iterate and ignore the metadata. 187if (index == 0 ) 188return loadBlob (ArtifactKeep ::Yes ,outblob ); 189 190uint32_t count = 1 ; 191for (auto artifact :m_associated ) 192 { 193if (artifact -> getDesc ().payload == ArtifactPayload ::Metadata || 194artifact -> getDesc ().payload == ArtifactPayload ::PostEmitMetadata ) 195continue ; 196if (count == index ) 197return artifact -> loadBlob (ArtifactKeep ::Yes ,outblob ); 198count ++ ; 199 } 200return SLANG_FAIL ; 201} 202 203SlangResult Artifact ::getMetadata (slang::IMetadata ** outMetadata ) 204{ 205// Find and return the associated metadata artifact. 206auto metadata = findAssociatedRepresentation < IArtifactPostEmitMetadata > (this ); 207if (!metadata ) 208return SLANG_E_NOT_AVAILABLE ; 209 210* outMetadata = static_cast < slang::IMetadata *> (metadata ); 211 (* outMetadata )-> addRef (); 212return SLANG_OK ; 213} 214 215SlangResult Artifact ::getOrCreateRepresentation ( 216const Guid & typeGuid , 217ArtifactKeep keep , 218ICastable ** outCastable ) 219{ 220auto handler = _getHandler (); 221return handler -> getOrCreateRepresentation (this ,typeGuid ,keep ,outCastable ); 222} 223 224SlangResult Artifact ::loadBlob (Keep keep ,ISlangBlob ** outBlob ) 225{ 226auto handler = _getHandler (); 227 228ComPtr < ICastable > castable ; 229SLANG_RETURN_ON_FAIL (handler -> getOrCreateRepresentation ( 230this , 231ISlangBlob ::getTypeGuid (), 232keep , 233castable .writeRef ())); 234 235ISlangBlob * blob = as < ISlangBlob > (castable ); 236blob -> addRef (); 237 238* outBlob = blob ; 239return SLANG_OK ; 240} 241 242void Artifact ::addAssociated (IArtifact * artifact ) 243{ 244SLANG_ASSERT (artifact ); 245m_associated .add (ComPtr < IArtifact > (artifact )); 246} 247 248static void * _findRepresentation (const ConstArrayView < ICastable *>& castables ,const Guid & guid ) 249{ 250for (const auto & cur :castables ) 251 { 252if (auto ptr = cur -> castAs (guid )) 253 { 254return ptr ; 255 } 256 } 257return nullptr ; 258} 259 260static void * _findRepresentation (const ConstArrayView < IArtifact *>& artifacts ,const Guid & guid ) 261{ 262for (auto child :artifacts ) 263 { 264if (auto rep = child -> findRepresentation (Artifact ::ContainedKind ::Representation ,guid )) 265 { 266return rep ; 267 } 268 } 269return nullptr ; 270} 271 272void * Artifact ::findRepresentation (ContainedKind kind ,const Guid & guid ) 273{ 274switch (kind ) 275 { 276case ContainedKind ::Associated : 277return _findRepresentation (_getRawView (m_associated ),guid ); 278case ContainedKind ::Representation : 279return _findRepresentation (_getRawView (m_representations ),guid ); 280case ContainedKind ::Children : 281 { 282_requireChildren (); 283return _findRepresentation (_getRawView (m_children ),guid ); 284 } 285 } 286return nullptr ; 287} 288 289Slice < IArtifact *> Artifact ::getAssociated () 290{ 291return SliceUtil ::asSlice (m_associated ); 292} 293 294void Artifact ::addRepresentation (ICastable * castable ) 295{ 296SLANG_ASSERT (castable ); 297 298auto view = _getRawView (m_representations ); 299if (view .indexOf (castable ) >=0 ) 300 { 301SLANG_ASSERT_FAILURE ("Already have this representation" ); 302return ; 303 } 304 305m_representations .add (ComPtr < ICastable > (castable )); 306} 307 308void Artifact ::addRepresentationUnknown (ISlangUnknown * unk ) 309{ 310SLANG_ASSERT (unk ); 311 312 { 313const auto view = makeConstArrayView ( 314 (ISlangUnknown * const * )m_representations .getBuffer (), 315m_representations .getCount ()); 316if (view .indexOf (unk ) >=0 ) 317 { 318SLANG_ASSERT_FAILURE ("Already have this representation" ); 319return ; 320 } 321 } 322 323ComPtr < ICastable > castable ; 324if (SLANG_SUCCEEDED (unk -> queryInterface (SLANG_IID_PPV_ARGS (castable .writeRef ())))&& castable ) 325 { 326if (_getRawView (m_representations ).indexOf (castable ) >=0 ) 327 { 328SLANG_ASSERT_FAILURE ("Already have this representation" ); 329return ; 330 } 331m_representations .add (castable ); 332 } 333else 334 { 335UnknownCastableAdapter * adapter = new UnknownCastableAdapter (unk ); 336m_representations .add (ComPtr < ICastable > (adapter )); 337 } 338} 339 340Slice < ICastable *> Artifact ::getRepresentations () 341{ 342return SliceUtil ::asSlice (m_representations ); 343} 344 345void Artifact ::setChildren (IArtifact * const * children ,Count count ) 346{ 347m_expandResult = SLANG_OK ; 348 349m_children .clearAndDeallocate (); 350m_children .setCount (count ); 351 352ComPtr < IArtifact >* dst = m_children .getBuffer (); 353for (Index i = 0 ;i < count ;++ i ) 354 { 355dst [i ]= children [i ]; 356 } 357} 358 359SlangResult Artifact ::expandChildren () 360{ 361auto handler = _getHandler (); 362return handler -> expandChildren (this ); 363} 364 365Slice < IArtifact *> Artifact ::getChildren () 366{ 367_requireChildren (); 368return SliceUtil ::asSlice (m_children ); 369} 370 371void Artifact ::addChild (IArtifact * artifact ) 372{ 373SLANG_ASSERT (artifact ); 374SLANG_ASSERT (_getRawView (m_children ).indexOf (artifact )< 0 ); 375 376_requireChildren (); 377 378m_children .add (ComPtr < IArtifact > (artifact )); 379} 380 381}// namespace Slang