SEB scény a Event Player ve FW 0.12.11
Jak ve firmware 0.12.11 použít Berry SEB.land a SEB.emit pro kauzální scény a časované segmenty eventových hodnot.
Co je SEB
Section titled “Co je SEB”SEB (Spectoda Event Batch) je malý binární soubor s diskrétními eventovými hodnotami/záznamy. Každý záznam obsahuje nativní hodnotu, label, Spectoda ID, prioritu a absolutní časový offset uvnitř segmentu. Landing nebo emit záznamu vyvolá běžné zpracování EventStateUpdate přes EventStore.
SEB není authoring ani projektový formát Playeru. Neobsahuje název scény,
Tracku, loop ani seek pravidla. Tyto informace drží projektový Berry script.
Statický soubor player.show v3 je malý manifest jednoho globálního mixed-ID
streamu v pevných NetworkStorage slotech player.NNN.
Jeden SEB segment má nejvýše 340 záznamů, velikost nejvýše 4 092 bajtů a délku
nejvýše 65 535 ms. Tím využije jeden 4 096B datový blok LittleFS; metadata
souboru jsou uložena samostatně. Runtime nadále přijme v jednom atomickém
příspěvku nejvýše 340 splatných Eventů, takže jedna maximální Cue Group ve
stejném čase napříč všemi ID jde commitnout atomicky. Celkový 341. pending Event
selže před změnou fronty, EventStore nebo cursoru. Cue Group se nikdy
nerozdělí. Delší show se skládá z více seřazených segmentů.
Normativní byte layout a všechna validační pravidla
udržuje firmware v souboru
components/spectoda-library/docs/SEB_V1.md; zde je
přesná review verze pro FW 0.12.11.
SEB.land a SEB.emit
Section titled “SEB.land a SEB.emit”Pro distribuovaný Player používejte na všech připravených kontrolerech
SEB.land. Události vstoupí do lokálního EventStore se stejným síťovým časem,
ale nevznikne okamžitý broadcast execute bytecode. Běžná synchronizace
EventStore později dorovná kontroler, který událost ve správný okamžik
nelandnul.
SEB.emit použijte jen tehdy, když existuje právě jeden autoritativní zdroj.
Pouštět SEB.emit na všech kontrolerech by zbytečně násobilo síťové události.
Skalární API zůstává ve FW 0.12.11 zachované:
spectoda.landEvent(label, value, ids, vtype)spectoda.landEvent(label, value, ids, vtype, event_millis)spectoda.emitEvent(label, value, ids, vtype)spectoda.emitEvent(label, value, ids, vtype, event_millis)ids může být jedno ID, seznam ID nebo nil pro broadcast. Volitelný
event_millis zachová přesný kauzální lokální čas původní události. Pro dávky
používejte komponentu SEB; nejde o plural variantu skalární metody.
var result = SEB.land("segment-000.seb", { "source": "networkStorage", "at": segment_at, "cursor": cursor, "until": position})
if result["ok"] cursor = result["cursor"]else print("SEB error", result["error"])endVýznam at, cursor a until
Section titled “Význam at, cursor a until”atje lokální wrappingcontroller.millis()token odpovídající offsetu nula. Pro časovaný segment je povinný.cursorje index prvního dosud nespotřebovaného zdrojového záznamu. Výchozí hodnota je0.untilje včetně zahrnutý offset, po který se mají zpracovat splatné záznamy. Výchozí hodnota je0.source: "networkStorage"určuje, že první argument je název souboru. Bez něj zůstává první argument Berry hodnotabytes.
Jedno volání vezme maximální splatný prefix. Nejdřív jej celý ověří a rezervuje a teprve potom atomicky zapíše. Při chybě zůstane EventStore, fronta i cursor beze změny, takže Berry může volání bezpečně zopakovat.
Jeden kontrakt args.at pokrývá tři explicitní časové domény:
timeline.at(segmentStart)převede pozici Player timeline na lokální wrapping millis token;event_millisz triggeruEVS.cbzachová Network-clock kauzalitu události při vyvolání scény;controller.millis()znamená právě teď na tomto Controlleru.
Network clock zůstává autoritou pro řazení EventStore. SEB přijímá pouze lokální token a nemá žádný timeline-specific overload.
SEB si neponechá Berry pointer, filename, file handle, cursor ani Player stav.
Projekt musí zachovat bitově stejné at pro přesný pár zdroje a cursoru. Při
změně segmentu, seeku, loopu nebo změně časové projekce musí cursor resetovat
nebo nahradit.
Referenční Player řeší pause/resume jako explicitní vnější policy. S novou
projekcí odvodí nový pár filename/at a přenese jen známý index prvního
nespotřebovaného zdrojového záznamu. Toto číslo nepoužívejte s jiným zdrojem
ani s libovolným at.
Kauzální vyvolání scény
Section titled “Kauzální vyvolání scény”Scéna je obyčejný mixed-ID SEB s duration_ms = 0 a všemi offsety nula.
Trigger Event může nést label scény. Callback EVS.cb předá také přesný lokální
čas původní události; ten použijte jako at.
var scene = EVS("scene", ID255)
scene.cb = def(value, event_id, event_millis) if event_millis == nil || !value.is(31) return end
var name = value.get(31) + ".seb" var result = SEB.land(name, { "source": "networkStorage", "at": event_millis }) if !result["ok"] print("Invalid scene", result["error"]) endendTrigger $scene[ID255] samotný do souboru scény nekompilujte, jinak by vznikla
rekurze.
Scene recall vůbec nevolá timeline.at(). Zůstává kauzální i při pozastavené
timeline, protože callback dostal event_millis z trigger události.
player.show v3
Section titled “player.show v3”Copy-ready Player načte player.show a polluje timeline.getState().
Exact-EOF manifest má 12bajtovou hlavičku a jednu 10bajtovou položku pro každý
pevný segmentový slot:
- přesnou požadovanou NetworkStorage verzi jako
u48little-endian; - absolutní začátek segmentu na show timeline jako
u32little-endian.
Položka s indexem 0 znamená player.000, index 1 znamená player.001 a
tak dále až po player.999. Jména se neukládají. Berry získá lokální verzi z
spectoda.listNetworkStorageData() jako přesně 12znakový lowercase hex řetězec
a porovná ji bez převodu do 32bitového čísla.
Studio publikuje novější manifest jako první a změněné sloty po něm. Nejde o hot-update protokol: Controller zůstane neaktivní, dokud nemá všechny požadované verze a neověří SEB header i EOF. Chybějící soubory dodá běžná NetworkStorage synchronizace. Upload nijak nemění stav timeline.
Timeline, pauza a seek
Section titled “Timeline, pauza a seek”Běžný dopředný běh vybere aktuální segment podle absolutního začátku, spočítá
at přes timeline.at(segmentStart) a předá aktuální relativní pozici jako
until. Každý Controller landuje všechna ID ze stejného streamu. Běžná pauza
bez skoku timeline nedělá žádné SEB volání.
timeline.at(position) uchovává, že aktuální referenční pozice timeline P
platila v Network clock čase C, vypočte C + (position - P) a tento clock
převede na signed wrapping lokální token Controlleru. Stejný výpočet platí při
běhu i pauze, takže Controllery s rozdílnou latencí zpracování příkazu získají
stejný Network timestamp. Funkce vrací nil, pokud cílový clock není platný
nebo leží mimo jednoznačné wrapping okno ±2^31 ms.
Timeline pozice je samostatný 24hodinový kruh 0..86 399 999; hodnota
86 400 000 se normalizuje na 0. Přechod přes půlnoc proto zůstává spojitý
pro Player, Layer i animace. Projekce vybírá nejbližší výskyt v rozsahu ±12
hodin; přesný rozdíl 12 hodin je nejednoznačný a vrátí nil.
Pause/resume zachovává epoch, ale resume vytváří novou kauzální projekci;
Player odvodí nové at pro aktuální segment a ponechá již spotřebovaný
zdrojový prefix. Seek a loop epoch změní a znovu nastaví cursor.
Při seeku, loopu, rewind nebo 24hodinovém wrapu Player vybere Cue Group přesně v cíli, nebo bezprostředně před ním. Tuto jednu řídkou Group landne jednou v kauzálním čase seeku i při pauze a posune cursor až za ni. Resume ji proto nezopakuje a žádná budoucí Cue se nevybere.
Jde o řídké dorovnání, ne rekonstrukci kompletního stavu. Player nemaže EventStore ani nepřehrává starší historii. Eventy, které ve vybraném Cue nejsou, si ponechají existující EventStates. Tam, kde má libovolný seek obnovit celý vizuální stav, použijte kompletní Cue.
EventStore zůstává autoritou
Section titled “EventStore zůstává autoritou”SEB nemění EventState mimo EventStore. Poslední EventStateUpdate proto zůstává rozhodující i po pozdější synchronizaci historie a externě emitovaná událost může stav Playeru změnit běžnou cestou.
Hotové příklady
Section titled “Hotové příklady”Příklady používají jen syntetická ID a přesné NetworkStorage artefakty pro FW 0.12.11. Pro tvorbu show ve Studiu pokračujte na návod Event Player ve Spectoda Studiu.