Module: Glslkit::Bundle
- Defined in:
- lib/glslkit/bundle.rb
Overview
1プログラム分(vertex+fragment)を「前処理→Program化→検証→Manifest組み立て」
まで通す中間表現(M11b、SPEC-livereload.md §3.2)。core/rails/wasmのどれにも
属さない — Glslkit::WebGL::Embed はこれを .rb に整形するだけの薄い
ラッパーになり、Rails側のライブリロードは同じ結果をJSONに整形して返す
(シリアライズ形式だけが違う、というのがこのクラスを切り出した理由)。
.build は例外を投げない。前処理(#include解決)が失敗した場合も、
Validatorがエラーを返した場合も、結果は常に Result として返る。
例外にして呼び出し側に伝える/伝えないの判断は呼び出し側の役目
(Embedは前者、Railsのライブリロードエンドポイントは後者になる想定)。
Defined Under Namespace
Classes: Result
Constant Summary collapse
- PREPROCESS_ERRORS =
Preprocessor#process とその内部で使うResolverが実際に投げうる例外を 尽くす。ここに列挙されていない例外(想定外のバグ等)は握り潰さず そのまま伝播させる。
[ IncludeNotFound, CircularIncludeError, VersionConflictError, PathTraversalError ].freeze
Class Method Summary collapse
-
.build(resolver:, name:, vertex:, fragment:, line_directives: true, disabled_checks: [], urls: {vertex: vertex, fragment: fragment}, known_files: [], now: Time.now) ⇒ Object
resolver: #include解決に使うResolver(呼び出し側が用意する。FileSystem/Hash等)。 vertex/fragment: resolverへ渡すエントリポイントのリクエスト文字列(相対パス)。 urls: Manifestのstage.urlに載せる値。省略時はvertex/fragmentのパス自身を使う (Embedの用途。実URLが要るRails側は明示的に渡す)。 known_files: ポーリング用digest(§3.2 決定1)を、前処理が失敗した回にも 計算するための「前回成功時のfiles」。呼び出し側が持ち回る (Bundle自身はステートレスに保つ)。.
- .fallback_files(known_files, entry_points) ⇒ Object
-
.read_raw(resolver, path) ⇒ Object
digest計算専用の再読み込み。known_filesに含まれる「前回成功時のファイル」が その後削除されている等で読めなくなっていても、digest計算そのものは 落とさない(ポーリングを壊さないことを優先する。digestは変化を検知できれば 十分で、読めなかった1ファイルの厳密な反映までは求めない)。.
-
.source_digest(resolver, files) ⇒ Object
依存する全ソースファイルの生バイト列(前処理後のコードではない)を パスでソートして "path\0content" で連結し、SHA256を取る(決定1)。.
Class Method Details
.build(resolver:, name:, vertex:, fragment:, line_directives: true, disabled_checks: [], urls: {vertex: vertex, fragment: fragment}, known_files: [], now: Time.now) ⇒ Object
resolver: #include解決に使うResolver(呼び出し側が用意する。FileSystem/Hash等)。 vertex/fragment: resolverへ渡すエントリポイントのリクエスト文字列(相対パス)。 urls: Manifestのstage.urlに載せる値。省略時はvertex/fragmentのパス自身を使う (Embedの用途。実URLが要るRails側は明示的に渡す)。 known_files: ポーリング用digest(§3.2 決定1)を、前処理が失敗した回にも 計算するための「前回成功時のfiles」。呼び出し側が持ち回る (Bundle自身はステートレスに保つ)。
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/glslkit/bundle.rb', line 63 def build(resolver:, name:, vertex:, fragment:, line_directives: true, disabled_checks: [], urls: {vertex: vertex, fragment: fragment}, known_files: [], now: Time.now) preprocessor = Preprocessor.new(resolver: resolver, line_directives: line_directives) begin vertex_source = preprocessor.process(vertex) fragment_source = preprocessor.process(fragment) rescue *PREPROCESS_ERRORS => e digest = source_digest(resolver, fallback_files(known_files, [vertex, fragment])) return Result.new(name: name, kind: :preprocess, source_digest: digest, error: e) end program = Program.new(name: name, sources: {vertex: vertex_source, fragment: fragment_source}) validation = Validator.new(disabled: disabled_checks).validate(program) digest = source_digest(resolver, (vertex_source.source_map.files + fragment_source.source_map.files).uniq) unless validation.ok? return Result.new( name: name, kind: :validation, source_digest: digest, vertex: vertex_source, fragment: fragment_source, diagnostics: validation.diagnostics ) end manifest = Manifest.build(programs: [program], urls: {name => urls}, now: now) Result.new( name: name, source_digest: digest, vertex: vertex_source, fragment: fragment_source, manifest: manifest, diagnostics: validation.diagnostics ) end |
.fallback_files(known_files, entry_points) ⇒ Object
93 94 95 |
# File 'lib/glslkit/bundle.rb', line 93 def fallback_files(known_files, entry_points) (known_files.empty? ? entry_points : known_files + entry_points).uniq end |
.read_raw(resolver, path) ⇒ Object
digest計算専用の再読み込み。known_filesに含まれる「前回成功時のファイル」が その後削除されている等で読めなくなっていても、digest計算そのものは 落とさない(ポーリングを壊さないことを優先する。digestは変化を検知できれば 十分で、読めなかった1ファイルの厳密な反映までは求めない)。
111 112 113 114 115 116 |
# File 'lib/glslkit/bundle.rb', line 111 def read_raw(resolver, path) _, content = resolver.read(path, from: nil) content rescue nil end |
.source_digest(resolver, files) ⇒ Object
依存する全ソースファイルの生バイト列(前処理後のコードではない)を パスでソートして "path\0content" で連結し、SHA256を取る(決定1)。
99 100 101 102 103 104 105 |
# File 'lib/glslkit/bundle.rb', line 99 def source_digest(resolver, files) entries = files.sort.filter_map do |path| content = read_raw(resolver, path) "#{path}\0#{content}" unless content.nil? end Digest.hexdigest(entries.join) end |