updateFromMetadata method

void updateFromMetadata(
  1. Shader shader,
  2. Map<String, Object?> metadata
)

Re-reads parameter declarations from a regenerated shader and metadata (a hot-reloaded .fmat), preserving values the caller explicitly set.

For a parameter present before and after with the same type: an explicitly-set value is kept; otherwise the new default is taken, so editing a default in the .fmat takes effect live. New parameters take their new default; removed parameters are dropped. Sampler bindings are preserved by name. A parameter declared in metadata but absent from the compiled block (a transient bundle/metadata mismatch mid-reload) is skipped rather than throwing.

Implementation

void updateFromMetadata(gpu.Shader shader, Map<String, Object?> metadata) {
  final newBlockName =
      (metadata['uniform_block'] as String?) ?? 'MaterialParams';
  final slot = shader.getUniformSlot(newBlockName);

  final newLayout = <String, _ParamSlot>{};
  final newDefaults = <String, Object>{};
  for (final raw in (metadata['parameters'] as List?) ?? const []) {
    final p = (raw as Map).cast<String, Object?>();
    final name = p['name'] as String;
    final type = FmatType.fromToken(p['type'] as String);
    if (type == null) continue;
    final offset = slot.getMemberOffsetInBytes(name);
    if (offset == null) continue;
    final hint = (p['hint'] as Map?)?.cast<String, Object?>();
    newLayout[name] = _ParamSlot(
      type,
      offset,
      sourceColor: hint?['kind'] == 'source_color',
    );
    final defaultValue = p['default'];
    if (defaultValue != null) newDefaults[name] = defaultValue;
  }

  final newSamplerHints = <String, FmatHintKind?>{};
  for (final raw in (metadata['samplers'] as List?) ?? const []) {
    final s = (raw as Map).cast<String, Object?>();
    final hint = (s['hint'] as Map?)?.cast<String, Object?>();
    newSamplerHints[s['name'] as String] = _hintKind(
      hint?['kind'] as String?,
    );
  }

  _applyRefresh(
    newBlockName,
    slot.sizeInBytes ?? 0,
    newLayout,
    newDefaults,
    newSamplerHints,
  );
}