///|
pub fn Composer::add_composable_module(
self : Composer,
desc : ComposableModuleDescriptor,
) -> ComposableModuleDefinition raise ComposerError {
self.processed_module_cache.clear()
let metadata = get_preprocessor_metadata(desc.source, allow_defines=false) catch {
error => raise composer_error_from_metadata_error(error)
}
let module_name = composable_module_name_from_descriptor(desc, metadata.name)
let registry_rel_path = composable_module_registry_rel_path(desc, module_name)
let shader_defs = copy_shader_def_values(desc.shader_defs)
let effective_defs = metadata.effective_defs.copy()
let all_imports : @set.Set[String] = Set([])
let additional_imports = copy_import_definitions(desc.additional_imports)
let import_names : Array[String] = []
for import_binding in metadata.imports {
let import_name = import_binding.definition.import_path
if import_name != "" {
import_names.push(import_name)
}
}
for import_definition in additional_imports {
let import_name = import_definition.import_path
if import_name != "" {
import_names.push(import_name)
}
}
for import_name in import_names {
guard resolve_wgsl_semantic_import_module(
registry_rel_path,
import_name,
self.registry,
self.registry.copy_import_module_paths(),
)
is Some(resolved_module) else {
raise FailedToResolveImport(import_name)
}
let resolved_module_path = resolved_module.module_path()
all_imports.add(resolved_module_path)
if self.module_sets.get(resolved_module_path) is Some(imported_module) {
for effective_def in imported_module.effective_defs {
effective_defs.add(effective_def)
}
for entry in imported_module.shader_defs.iter() {
let (def_name, def_value) = entry
shader_defs.set(def_name, def_value)
}
}
}
for entry in shader_defs.iter() {
let (def_name, _) = entry
effective_defs.remove(def_name)
}
let source_with_additional_imports = prepend_wgsl_additional_imports(
desc.source,
additional_imports,
)
let definition = ComposableModuleDefinition(
module_name,
shader_defs,
set_strings_to_array(effective_defs),
all_imports,
)
composer_remove_composable_module_recursive(self, module_name)
ignore(
self.registry.register_source(
registry_rel_path,
source_with_additional_imports,
Some(module_name),
),
)
self.composable_module_registry_paths.set(module_name, registry_rel_path)
self.module_sets.set(module_name, definition)
match self.module_sets.get(module_name) {
Some(module_definition) => module_definition
None => abort("expected just-inserted composable module to exist")
}
}
///|
pub fn Composer::remove_composable_module(
self : Composer,
module_name : String,
) -> Unit {
self.processed_module_cache.clear()
composer_remove_composable_module_recursive(self, module_name)
}
///|
fn Composer::load_wgsl_source_required_raw(
self : Composer,
rel : String,
) -> String raise ComposerError {
let normalized_rel = normalize_shader_rel_path(rel)
if normalized_rel == "" {
return ""
}
match self.registry.registered_source(normalized_rel) {
Some(source) => source
None => raise MissingStartupRegisteredSource(normalized_rel)
}
}
///|
fn composer_error_from_preprocess_error(
error : PreprocessError,
) -> ComposerError {
match error {
UnknownShaderDef(name, _) => UnknownShaderDef(name)
UnknownShaderDefOperator(operator, _) => UnknownShaderDefOperator(operator)
InvalidShaderDefComparisonValue(name, value, expected, _) =>
InvalidShaderDefComparisonValue(name, value, expected)
ElseWithoutCondition(_) => ElseWithoutCondition
TooManyEndIfs(_) => TooManyEndIfs
NotEnoughEndIfs(_) => NotEnoughEndIfs
ImportParseError(message, _) => FailedToResolveImport(message)
GlslInvalidVersion(_) => GlslInvalidVersion
}
}
///|
fn composer_error_from_metadata_error(error : MetadataError) -> ComposerError {
match error {
ImportParseError(message, _) => FailedToResolveImport(message)
InvalidWgslDirective(line, _, reason) => InvalidWgslDirective(line, reason)
DefineInModule(_) => DefineInModule
}
}
///|
fn composer_error_from_wgsl_parse_error(
error : WgslParseError,
) -> ComposerError {
match error {
UnparsedDeclaration(text, offset) =>
InvalidWgslSyntax("declaration could not be parsed: \{text}", offset)
}
}
///|
fn validate_wgsl_translation_unit_strict(
source : String,
) -> Unit raise ComposerError {
if parse_glsl_version_directive(source) is Some(_) {
return
}
ignore(
parse_wgsl_translation_unit_strict(
mask_naga_oil_directives_for_wgsl(source),
),
) catch {
error => raise composer_error_from_wgsl_parse_error(error)
}
}
///|
fn apply_wgsl_ifdefs_strict_for_compose(
source : String,
active_defs : WgslActiveComposeDefs,
) -> String raise ComposerError {
apply_wgsl_ifdefs_strict(source, active_defs.shader_defs) catch {
error => raise composer_error_from_preprocess_error(error)
}
}