\b;Cvičení
Ovládejte na dálku jiného robota bez použití \l;komunikační stanice\u object\exchange;. Robot má za úkol přejet přes 6 modrých křížků. 

Hlavní role v tomto cvičení hrají:
1) \l;Pojízdné rameno\u object\botgr; bez baterie, tím pádem nepojízdné. To je velitel, kterého musíte naprogramovat, aby předával povely dělníkovi.
2) \l;Cvičný robot\u object\bottr;, který už je naprogramovaný a jen čeká na povely od velitele.

Povely budeme ukládat do fronty, aby velitel mohl poslat více povelů najednou bez čekání na jejich dokončení. K tomu můžeme využít \l;pole\u cbot\array;.

\b;Dělník
Nejprve si musíme vysvětlit, jak funguje program dělníka. \l;Třída\u cbot\class; \c;order\n; obsahuje dva atributy: \c;m_type\n; určuje příkaz, který se má provést (\c;move\n; nebo \c;turn\n;) a \c;m_param\n; určuje délku jízdy nebo úhel otočení:

\c;\s;\l;public\u cbot\public; \l;class\u cbot\class; order
\s;{
\s;	\l;int\u cbot\int;    m_type;
\s;	\l;float\u cbot\float;  m_param;
\s;}
\n;
Další \l;třída\u cbot\class; \c;exchange\n; poskytuje mechanismus pro předávání povelů. V ní je deklarovaný \l;statický\u cbot\static; atribut \c;m_fifo\n;, kam budeme povely ukládat. Klíčové slovo \c;static\n; znamená, že všechny instance \l;třídy\u cbot\class; \c;exchange\n; budou atribut \c;m_fifo\n; sdílet mezi sebou.

\c;\s;{
\s;	\l;static\u cbot\static; \l;private\u cbot\private; order m_fifo[] = null;
\n;
Velitel bude pro předání povelu volat metodu \c;put\n;. Povel se jednoduše přidá na konec pole \c;m_fifo\n;:

\c;\s;	\l;synchronized\u cbot\synchro; void put(order a)
\s;	{
\s;		m_fifo[sizeof(m_fifo)] = a;
\s;	}
\n;
Dělník si pak povely přečte pomocí metody \c;get\n;. Tato metoda vrátí další povel, který se má provést. Pokud je fronta prázdná, metoda vrátí \c;null\n; a robot musí čekat. Jinak vrátí první povel ve frontě a zbývající povely "posune" na uvolněné místo. Protože pole nelze zkrátit, použijeme k tomu dočasné pole \c;copy\n;:

\c;\s;	\l;synchronized\u cbot\synchro; order get()
\s;	{
\s;		if ( sizeof(m_fifo) == 0 )  return null;
\s;
\s;		order a = m_fifo[0];
\s;		order copy[] = null;
\s;		for ( int i=1 ; i<sizeof(m_fifo) ; i++ )
\s;		{
\s;			copy[i-1] = m_fifo[i];
\s;		}
\s;		m_fifo = copy;
\s;		return a;
\s;	}
\n;
Hlavní program dělníka obsahuje instanci třídy \c;exchange\n; nazvanou \c;list\n;. Závorky za slovem \c;list\n; znamenají, že vytváříme instanci třídy \c;exchange\n;.

\c;\s;\l;extern\u cbot\extern; void object::Slave5( )
\s;{
\s;	exchange list();
\s;	order    todo;
\n;
Vnější cyklus \c;while\n; se opakuje donekonečna. Vnitřní cyklus \c;while\n; čeká na povel a stále volá metodu \c;get\n; třídy \c;exchange\n;. Když metoda \c;get\n; vrátí jinou hodnotu než \c;null\n;, vnitřní cyklus skončí.

\c;\s;	\l;while\u cbot\while; ( true )
\s;	{
\s;		\l;while\u cbot\while; ( true )
\s;		{
\s;			todo = list.get();
\s;			if ( todo != null )  break;
\s;			wait(1);
\s;		}
\n;
Když máme povel uložený v proměnné \c;todo\n;, zbývá ho jen provést:

\c;\s;		if ( todo.m_type == 1 )
\s;		{
\s;			move(todo.m_param);
\s;		}
\s;		else if ( todo.m_type == 2 )
\s;		{
\s;			turn(todo.m_param);
\s;		}
\s;		else
\s;		{
\s;			message("Unknown order");
\s;		}
\s;	}
\s;}
\n;
\b;Velitel
Pro velitele napíšeme funkci \c;SendOrder\n;, která pošle povel dělníkovi:

\c;\s;void object::SendOrder(float order, float param)
\s;{
\s;	exchange list();
\s;	order    todo();
\s;	
\s;	todo.m_type = order;
\s;	todo.m_param = param;
\s;	list.put(todo);
\s;}
\n;
Dál už bude hlavní program velitele celkem jednoduchý:

\c;\s;extern void object::Ovladac5( )
\s;{
\s;	SendOrder(1, 20);  // move(20);
\s;	SendOrder(2, 90);  // turn(90);
\s;	SendOrder(1, 20);  // move(20);
\s;	SendOrder(2, 90);  // turn(90);
\s;	SendOrder(1, 10);  // move(10);
\s;	SendOrder(2, 90);  // turn(90);
\s;	SendOrder(1, 10);  // move(10);
\s;	SendOrder(2,-90);  // turn(-90);
\s;	SendOrder(1, 10);  // move(10);
\s;}
\n;
Tyto instrukce si můžete kdykoliv znovu přečíst klávesou \key;\key help;\norm;.

\t;Užitečné odkazy
\l;Ovládání\u command; a \l;programování\u cbot;.
