Test framework je pripojený k serveru na porte 3200, odkiaľ od neho prijíma správy o aktuálnom stave kompletnej simulácie. Tieto správy sú podľa protokolu SimSparku S-výrazy obsahujúce niekoľko špecifických údajov a popisujúce graf scény. Test framework z tohto grafu vyberá pre seba zaujímavé informácie (poloha lopty, poloha hráčov).
Monitorovanie beží v samostatnom threade v triede RobocupMonitor''
, ktorej inštancia sa dá získať metódou getMonitorInstance()''
. Táto trieda sa pri každej príchodzej správe zo serveru pozrie do hlavičky správy, na základe čoho určí o aký typ správy sa jedná.
Celý stav simulácie - informácie z oboch typoch správ a kompletná scéna - je uložený v objekte triedy SimulationState''
. Takýto objekt s aktuálnym stavom vlastní trieda RobocupMonitor
, ktorá ho priebežne updatuje na základe príchodzích správ. Dá sa z nej získať metódou getSimulationState''
.
Takisto je možné sledovať všetky updaty týchto údajov zaregistrovaním observeru implementujúceho ISimulationStateObserver''
v objekte triedy SimulationState
.
Každá správa zo servera prijatá triedou RobocupMonitor
je najprv rozparsovaná
EnvironmentMessageParser''
GameStateMessageParser''
Po oboch typoch správ vždy nasleduje graf scény, buď kompletný, alebo len čiastočný (vyjadrujúci zmenu oproti predchádzajúcemu stavu). Tento je rozparsovaný pomocou tried SceneGraphHeaderPartParser''
a SceneGraphPartParser''
Trieda RobocupMonitor
teda rozparsuje správy príslušným parserom do objektov podtried triedy Message''
. Tieto dáta sú následne aplikované triedou MessageInterpreter''
. Okrem informácií z environment správ a game state správ, ktoré sa uložia do aktuálneho stavu simulácie, je treba spracovať graf scény, čo sa deje vnútri triedy SceneUpdater''
. Táto okrem vytvorenia celého grafu z neho vyberie uzol reprezentujúci loptu (uloží sa do jednoduchého 3D vektora Scene.ballLocation''
) a uzly reprezentujúce hráčov (objekty triedy Player''
), ktoré sú prepojené s objektami agentov AgentJim''
. Toto prepojenie je popísané v nasledovnej podkapitole.
Ako už bolo uvedené, s týmito údajmi sa dá pracovať pomocou objektu triedy SimulationState''
získanej volaním getSimulationState''
z RobocupMonitor
. Zmeny je možné sledovať pomocou observeru ISimulationStateObserver''
.
Pre jednoduchšiu prácu so stavmi simulácie v rôznych časoch možno použiť aj triedu MeasurableInformation''
, ktorá si skopíruje aktuálny stav simulácie a neskôr možno dva takéto objekty porovnať.
Server posiela graf scény len vo forme 3D objektov, informácia o tom ku ktorému pripojenému agentovi ktorý objekt patrí sa tam priamo nenachádza, treba ju teda získať iným spôsobom. Jedna z možností by možno (?) bola zistenie podľa materiálov (farba určí tím, číslo na drese hráča?). Ja sa však spolieham na fakt, že modely sú posielané v poradí, v akom sa hráči pripojili. Toto síce nie je priamo popísané v protokole, takže to možno nie je 100% spoľahlivé, no podľa mojich testov to v praxi funguje. TODO:: pridať poznámku do príslušnej časti kódu, že ak to prestane fungovať, treba overiť toto.
Na využitie týchto informácií je treba ukladať informácie o poradí pripojenia agentov. Toto je uložené v AgentManager.orderedAgents''
. Pretože objekt grafu scény bude pri pripojení agenta vytvorený skôr než objekt AgentJim''
, treba túto asociáciu vytvoriť oneskorene. To funguje tak že
Player''
) sa do neho uloží jeho poradie. Ak príslušný AgentJim
objekt už existuje, priradí sa mu (podľa poradia daného AgentJim objektu). V opačnom prípade sa zaradí do frontu v triede AgentManager
, aby sa prepojenie vytvorilo pri vytvorení objektu AgentJim
AgentJim
sa pozrie či sú nejaké Player
objekty vo fronte, ak áno, vyberie sa prvý a vytvorí sa asociácia.Teoreticky to nemusí byť úplne spoľahlivé, hlavne keď sa pripojí viac agentov vo veľmi krátkom časovom úseku (prakticky naraz). V praxi to ale funguje relatívne dobre.
Objekt triedy Player sa dá z objektu triedy AgentJim získať pomocou metódy getSceneGraphPlayer''
. Tá vráti poradie Player objektu v zozname vrátanom metódou getPlayers triedy Scene''
. Objekt triedy Scene sa získa metódou getScene z objektu triedy SimulationState. V prípade, že prepojenie medzi agentom a objektom hráča v dátach z monitora ešte nebolo vytvorené, vráti getSceneGraphPlayer číslo -1.
Objekt triedy AgentJim sa z objektu triedy Player dá získať metódou getAssociatedAgent.
Podrobnosti o životnom cykle AgentJim
objektov sú v sekcii Spúšťanie a riadenie agentov.