yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// slang-artifact-util.cpp 2#include "slang-artifact-util.h" 3 4#include "../core/slang-castable.h" 5#include "../core/slang-io.h" 6#include "slang-artifact-desc-util.h" 7#include "slang-artifact-impl.h" 8#include "slang-artifact-representation-impl.h" 9 10namespace Slang 11{ 12 13static bool _checkSelf (ArtifactUtil ::FindStyle findStyle ) 14{ 15return Index (findStyle ) <=Index (ArtifactUtil ::FindStyle ::SelfOrChildren ); 16} 17 18static bool _checkChildren (ArtifactUtil ::FindStyle findStyle ) 19{ 20return Index (findStyle ) >=Index (ArtifactUtil ::FindStyle ::SelfOrChildren ); 21} 22 23static bool _checkRecursive (ArtifactUtil ::FindStyle findStyle ) 24{ 25return findStyle == ArtifactUtil ::FindStyle ::Recursive || 26findStyle == ArtifactUtil ::FindStyle ::ChildrenRecursive ; 27} 28 29/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */ 30 31/* static */ ComPtr < IArtifact > ArtifactUtil ::createArtifact ( 32const ArtifactDesc & desc , 33const char * name ) 34{ 35auto artifact = createArtifact (desc ); 36artifact -> setName (name ); 37return artifact ; 38} 39 40/* static */ ComPtr < IArtifact > ArtifactUtil ::createArtifact (const ArtifactDesc & desc ) 41{ 42return Artifact ::create (desc ); 43} 44 45/* static */ ComPtr < IArtifact > ArtifactUtil ::createArtifactForCompileTarget ( 46SlangCompileTarget target ) 47{ 48auto desc = ArtifactDescUtil ::makeDescForCompileTarget (target ); 49return createArtifact (desc ); 50} 51 52/* static */ bool ArtifactUtil ::isSignificant (IArtifact * artifact ) 53{ 54return isSignificant (artifact -> getDesc ()); 55} 56 57/* static */ bool ArtifactUtil ::isSignificant (const ArtifactDesc & desc ) 58{ 59// Containers are not significant as of themselves, they may contain something tho 60if (isDerivedFrom (desc .kind ,ArtifactKind ::Container )) 61 { 62return false; 63 } 64 65// If it has no payload.. we are done 66if (desc .payload == ArtifactPayload ::None || desc .payload == ArtifactPayload ::Invalid ) 67 { 68return false; 69 } 70 71// If it's binary like or assembly/source we it's significant 72if (isDerivedFrom (desc .kind ,ArtifactKind ::CompileBinary )|| 73desc .kind == ArtifactKind ::Assembly || desc .kind == ArtifactKind ::Source ) 74 { 75return true; 76 } 77 78/* Hmm, we might want to have a base class for 'significant' payloads, 79where signifiance here means somewhat approximately 'the meat' of a compilation result, 80as contrasted with 'meta data', 'diagnostics etc'*/ 81if (isDerivedFrom (desc .payload ,ArtifactPayload ::Metadata )) 82 { 83return false; 84 } 85 86/* We currently can't write out diagnostics, so for now we'll say they are insignificant */ 87if (isDerivedFrom (desc .payload ,ArtifactPayload ::Diagnostics )) 88 { 89return false; 90 } 91 92return true; 93} 94 95 96/* static */ bool ArtifactUtil ::isSignificant (IArtifact * artifact ,void * data ) 97{ 98SLANG_UNUSED (data ); 99return isSignificant (artifact -> getDesc ()); 100} 101 102/* static */ IArtifact * ArtifactUtil ::findSignificant (IArtifact * artifact ) 103{ 104return findArtifactByPredicate ( 105artifact , 106FindStyle ::SelfOrChildren , 107& ArtifactUtil ::isSignificant , 108nullptr ); 109} 110 111UnownedStringSlice ArtifactUtil ::findPath (IArtifact * artifact ) 112{ 113// If a name is set we'll just use that 114 { 115const UnownedStringSlice name (artifact -> getName ()); 116if (name .getLength ()) 117 { 118return name ; 119 } 120 } 121 122IPathArtifactRepresentation * bestRep = nullptr ; 123 124// Look for a rep with a path. Prefer IExtFile because a IOSFile might be a temporary file 125for (auto rep :artifact -> getRepresentations ()) 126 { 127if (auto pathRep = as < IPathArtifactRepresentation > (rep )) 128 { 129if (pathRep -> getPathType ()== SLANG_PATH_TYPE_FILE && 130 (bestRep == nullptr || as < IExtFileArtifactRepresentation > (rep ))) 131 { 132bestRep = pathRep ; 133 } 134 } 135 } 136 137const UnownedStringSlice name = 138bestRep ?UnownedStringSlice (bestRep -> getPath ()) :UnownedStringSlice (); 139return name .getLength () ?name :UnownedStringSlice (); 140} 141 142/* static */ UnownedStringSlice ArtifactUtil ::inferExtension (IArtifact * artifact ) 143{ 144const UnownedStringSlice path = findPath (artifact ); 145if (path .getLength ()) 146 { 147auto ext = Path ::getPathExt (UnownedStringSlice (path )); 148if (ext .getLength ()) 149 { 150return ext ; 151 } 152 } 153return UnownedStringSlice (); 154} 155 156/* static */ UnownedStringSlice ArtifactUtil ::findName (IArtifact * artifact ) 157{ 158const UnownedStringSlice path = findPath (artifact ); 159const Index pos = Path ::findLastSeparatorIndex (path ); 160return (pos >=0 ) ?path .tail (pos + 1 ) :path ; 161} 162 163static SlangResult _calcInferred ( 164IArtifact * artifact , 165const UnownedStringSlice & basePath , 166StringBuilder & outPath ) 167{ 168auto ext = ArtifactUtil ::inferExtension (artifact ); 169 170// If no extension was determined by inferring, go with unknown 171if (ext .begin ()== nullptr ) 172 { 173ext = toSlice ("unknown" ); 174 } 175 176outPath .clear (); 177outPath .append (basePath ); 178if (ext .getLength ()) 179 { 180outPath .appendChar ('.' ); 181outPath .append (ext ); 182 } 183return SLANG_OK ; 184} 185 186/* static */ SlangResult ArtifactUtil ::calcPath ( 187IArtifact * artifact , 188const UnownedStringSlice & basePath , 189StringBuilder & outPath ) 190{ 191if (ArtifactDescUtil ::hasDefinedNameForDesc (artifact -> getDesc ())) 192 { 193return ArtifactDescUtil ::calcPathForDesc (artifact -> getDesc (),basePath ,outPath ); 194 } 195else 196 { 197return _calcInferred (artifact ,basePath ,outPath ); 198 } 199} 200 201/* static */ SlangResult ArtifactUtil ::calcName ( 202IArtifact * artifact , 203const UnownedStringSlice & baseName , 204StringBuilder & outName ) 205{ 206if (ArtifactDescUtil ::hasDefinedNameForDesc (artifact -> getDesc ())) 207 { 208return ArtifactDescUtil ::calcNameForDesc (artifact -> getDesc (),baseName ,outName ); 209 } 210else 211 { 212return _calcInferred (artifact ,baseName ,outName ); 213 } 214} 215 216static bool _isByDerivedDesc (IArtifact * artifact ,void * data ) 217{ 218const ArtifactDesc & desc = * (const ArtifactDesc * )data ; 219return ArtifactDescUtil ::isDescDerivedFrom (artifact -> getDesc (),desc ); 220} 221 222static bool _isDesc (IArtifact * artifact ,void * data ) 223{ 224const ArtifactDesc & desc = * (const ArtifactDesc * )data ; 225return artifact -> getDesc ()== desc ; 226} 227 228static bool _isName (IArtifact * artifact ,void * data ) 229{ 230const char * name = (const char * )data ; 231const auto artifactName = artifact -> getName (); 232 233if (name == nullptr || artifactName == nullptr ) 234 { 235return name == artifactName ; 236 } 237return ::strcmp (name ,artifactName )== 0 ; 238} 239 240/* static */ IArtifact * ArtifactUtil ::findArtifactByDerivedDesc ( 241IArtifact * artifact , 242FindStyle findStyle , 243const ArtifactDesc & desc ) 244{ 245return findArtifactByPredicate ( 246artifact , 247findStyle , 248_isByDerivedDesc , 249& const_cast < ArtifactDesc &> (desc )); 250} 251 252/* static */ IArtifact * ArtifactUtil ::findArtifactByName ( 253IArtifact * artifact , 254FindStyle findStyle , 255const char * name ) 256{ 257return findArtifactByPredicate (artifact ,findStyle ,_isName ,const_cast < char *> (name )); 258} 259 260/* static */ IArtifact * ArtifactUtil ::findArtifactByDesc ( 261IArtifact * artifact , 262FindStyle findStyle , 263const ArtifactDesc & desc ) 264{ 265return findArtifactByPredicate (artifact ,findStyle ,_isDesc ,& const_cast < ArtifactDesc &> (desc )); 266} 267 268/* static */ IArtifact * ArtifactUtil ::findArtifactByPredicate ( 269IArtifact * artifact , 270FindStyle findStyle , 271FindFunc func , 272void * data ) 273{ 274if (_checkSelf (findStyle )&& func (artifact ,data )) 275 { 276return artifact ; 277 } 278 279if (!_checkChildren (findStyle )) 280 { 281return nullptr ; 282 } 283 284// Expand the children so we can search them 285artifact -> expandChildren (); 286 287auto children = artifact -> getChildren (); 288if (children .count == 0 ) 289 { 290return nullptr ; 291 } 292 293// Check the children 294for (auto child :children ) 295 { 296if (func (child ,data )) 297 { 298return child ; 299 } 300 } 301 302// If it's recursive, we check all the children of children 303if (_checkRecursive (findStyle )) 304 { 305for (auto child :children ) 306 { 307if (auto found = 308findArtifactByPredicate (child ,FindStyle ::ChildrenRecursive ,func ,data )) 309 { 310return found ; 311 } 312 } 313 } 314 315return nullptr ; 316} 317 318/* static */ void ArtifactUtil ::addAssociated ( 319IArtifact * artifact , 320IArtifactPostEmitMetadata * metadata ) 321{ 322if (metadata ) 323 { 324auto metadataArtifact = ArtifactUtil ::createArtifact ( 325ArtifactDesc ::make (ArtifactKind ::Instance ,ArtifactPayload ::PostEmitMetadata )); 326metadataArtifact -> addRepresentation (metadata ); 327artifact -> addAssociated (metadataArtifact ); 328 } 329} 330 331/* static */ void ArtifactUtil ::addAssociated ( 332IArtifact * artifact , 333IArtifactDiagnostics * diagnostics ) 334{ 335if (diagnostics ) 336 { 337auto diagnosticsArtifact = ArtifactUtil ::createArtifact ( 338ArtifactDesc ::make (ArtifactKind ::Instance ,ArtifactPayload ::Diagnostics )); 339diagnosticsArtifact -> addRepresentation (diagnostics ); 340artifact -> addAssociated (diagnosticsArtifact ); 341 } 342} 343 344}// namespace Slang