<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ondra[sej] Blog &#187; .NET</title>
	<atom:link href="http://www.ondrejsykora.com/blog/category/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ondrejsykora.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 21 Mar 2010 13:17:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>C# události pro callback funkce</title>
		<link>http://www.ondrejsykora.com/blog/2006/07/31/c-udalosti-pro-callback-funkce/</link>
		<comments>http://www.ondrejsykora.com/blog/2006/07/31/c-udalosti-pro-callback-funkce/#comments</comments>
		<pubDate>Mon, 31 Jul 2006 19:28:48 +0000</pubDate>
		<dc:creator>ondrasej</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://ondra.sykorky.cz/blog/2006/07/31/c-udalosti-pro-callback-funkce/</guid>
		<description><![CDATA[Události (event) v .NET framework jsou efektivní a velmi jednoduchý způsob, jak implementovat návrhový vzor observer. Klíčové slovo event zná asi každý, kdo s C# přišel do styku. Při práci na .NET wrapperu pro SQLite jsem ale narazil na zajímavý problém &#8211; jak zajistit, aby callback funkce vyvolávající událost byla zaregistrována, jen pokud na událost [...]]]></description>
			<content:encoded><![CDATA[<p>Události (<em>event</em>) v .NET framework jsou efektivní a velmi jednoduchý způsob, jak implementovat návrhový vzor <em>observer</em>. Klíčové slovo <code>event</code> zná asi každý, kdo s C# přišel do styku. Při práci na .NET wrapperu pro SQLite jsem ale narazil na zajímavý problém &#8211; jak zajistit, aby callback funkce vyvolávající událost byla zaregistrována, jen pokud na událost čeká alespoń jeden klient?<br />
<span id="more-152"></span><br />
V duchu ostatních komponent v .NET framework by bylo očekavatelné, že by pro třídu reprezentující událost byly definované události <code>AddDelegate</code> a <code>RemoveDelegate</code> &#8211; tím bychom ale objekt definovali rekursivně tak, že každá jeho instance by obsahovala instanci objektu stejné třídy. Což pochopitelně může vést při implementaci k nekonečným problémům s nekonečnými rekursivními strukturami.</p>
<h3>Jak se překládají události</h3>
<pre>
<strong>class</strong> PozarniAlarm {
  <strong>public event</strong> EventHandler Hori;
}
</pre>
<p>Při pohledu na kód vygenerovaný překladačem pro událost je vidět, že pro událost je překladačem vygenerovaný delegát se stejnou signaturou, jakou má událost a se stejným jménem jako má událost; dále pro ni jsou vygenerovány metody <code>add_Hori(EventHandler)</code> a <code>remove_Hori(EventHandler)</code>.</p>
<p>Pokud v kódu pracujeme s událostí pomocí jejího názvu, až na operátory <code>+=</code> a <code>-=</code> pracujeme právě s tímto delegátem. Zmíněné operátory se pochopitelně přeloží na volání odpovídající metody <code>add_Hori</code>, nebo <code>remove_Hori</code>.<br />
Události, které by zachycovaly přidání nebo odebrání klienta události neexistují, ale nabízí se otázka, jestli by nebylo možné nějakým způsobem přetížit ony metody pro <code>+=</code> a <code>-=</code>. A jak zní odpověď? Ale samozřejmě&#8230;</p>
<h3>Vlastní <em>add</em> a <em>remove</em></h3>
<p>Podobně jako se u properties zadávají bloky kódu pro přečtení a zápis hodnoty, zadávají se i bloky kódu pro přidání a odebrání handleru, celková struktura je properties velmi podobná.</p>
<pre>
<strong>class</strong> PozarniAlarm {
  <strong>public event</strong> EventHandler Hori {
    <strong>add</strong> {
      <em>// ... kód pro přidání obsluhy ...</em>
    }
    <strong>remove</strong> {
      <em>// ... kód pro odebrání obsluhy ...</em>
    }
  }
}
</pre>
<p>Pokud části <em>add</em> a <em>remove</em> neuvedete, překladač automaticky za vás vygeneruje kód analogický tomuto pro přidávání</p>
<pre>
Hori = (EventHandler)EventHandler.Combine(Hori, value);
</pre>
<p>a tomuto pro odebírání</p>
<pre>
Hori = (EventHandler)EventHandler.Remove(Hori, value);
</pre>
<p><code>Hori</code> v těchto blocích kódu samozřejmě vystupuje ve významu delegáta, ve kterém se akumulují všechny delegáty přidané k události pomocí operátoru <code>+=</code>.</p>
<p>Pokud naopak bloky <em>add</em> a <em>remove</em> zadáme, překladač automaticky negeneruje proměnnou akumulující přidané delegáty a je nutné se o ni postarat. A tato proměnná, kterou pro událost vytvoříme ručně bohužel nesmí mít stejné jméno jako událost. Škoda&#8230;</p>
<h3>Spojení s callback funkcí</h3>
<p>V tomto bodě už je jednoduché do procesu vstoupit a ve vhodnou chvíli zaregistrovat svou callback funkci, která událost vyvolává.</p>
<pre>
<strong>class</strong> PozarniAlarm {
  <strong>public event</strong> EventHandler Hori {
    <strong>add</strong> {
      <em>// zjednodušená syntaxe pro spojování delegátů</em>
      m_HoriListeners += value;
      <em>// pokud se k události přihlásil první čekatel, zaregistruj
      // callback funkci</em>
      if(m_HoriListeners.GetInvocationList().Length == 1)
        RegisterCallback();
    }
    <strong>remove</strong> {
      <em>// pokud se odhlašuje poslední čekatel, odregistruj
      callback funkci</em>
      if(m_HoriListeners.GetInvocationList().Length == 1)
        UnregisterCallback();
      m_HoriListeners -= value;
    }
  }
  <em>// pro události, kde jsou zadané add a remove se proměnná
  // udržující seznam přidaných delegátů nevygeneruje
  // automaticky, musíme si jí vyrobit sami</em>
  <strong>private</strong> EventHandler m_HoriListeners;

  <strong>private void</strong> RegisterCallback() {
    <em>// ... proveď registraci callback funkce vyvolávající
    //     událost Hori ...</em>
  }

  <strong>private void</strong> UnregisterCallback() {
    <em>// ... zruš registraci callback funkce vyvolávající
    //     událost Hori ...</em>
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ondrejsykora.com/blog/2006/07/31/c-udalosti-pro-callback-funkce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3D grafika pro .NET snadno a rychle</title>
		<link>http://www.ondrejsykora.com/blog/2006/04/21/3d-grafika-pro-net-snadno-a-rychle/</link>
		<comments>http://www.ondrejsykora.com/blog/2006/04/21/3d-grafika-pro-net-snadno-a-rychle/#comments</comments>
		<pubDate>Thu, 20 Apr 2006 22:23:25 +0000</pubDate>
		<dc:creator>ondrasej</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://ondra.sykorky.cz/blog/1999/11/30/3d-grafika-pro-net-snadno-a-rychle/</guid>
		<description><![CDATA[Při vývoji aplikaci (zejména v oblasti zpracování dat) se čas od času vyskytne potřeba zobrazit zpracovávaná data. V případě, že vyvíjená aplikace je jen prototyp nebo nepočítáte s jejím dalším využitím, je zbytečné učit se kvůli jednomu experimentu nové a komplexní API pro zobrazení dat. Zvláště v případě, že již máte z dřívějších dob zkušenosti [...]]]></description>
			<content:encoded><![CDATA[<p>Při vývoji aplikaci (zejména v oblasti zpracování dat) se čas od času vyskytne potřeba zobrazit zpracovávaná data. V případě, že vyvíjená aplikace je jen prototyp nebo nepočítáte s jejím dalším využitím, je zbytečné učit se kvůli jednomu experimentu nové a komplexní API pro zobrazení dat. Zvláště v případě, že již máte z dřívějších dob zkušenosti s jiným rozhraním, například s OpenGL.</p>
<p><span id="more-148"></span></p>
<p>Právě do takové situace jsem se dostal při práci na programu pro seminář k přednášce Implementace neuronových sítí II. Mojim cílem bylo rychle a s vynaložením co nejmenší námahy naprogramovat zobrazení kohonenovské sítě operující v trojrozměrném vstupním prostoru (jednotlivé neurony lze reprezentovat jako body v 3D prostoru).</p>
<p>Požadovaným výsledkem bylo zobrazení několika desítek neuronů a zobrazení spojů mezi sousedními neurony v mřížce. Pro reprezentaci neuronu bohatě postačí &#8220;koule&#8221; složená z dvacítky polygonů, pro spoje jednoduché čáry. Dokud jsem síť potřeboval zobrazit jen ve dvou rozměrech, bylo možné používat velice komfortní grafické funkce z prostoru <em>System.Drawing</em>. S druhým rozměrem ale jejich možnosti končí a Microsoftem podporované <em>Managed DirectX</em> je dimenzované pro větší projekty vyžadující vyšší výkon a možnost využívat pokročilé funkce moderních grafických karet. Zřejmě i proto v něm chybí možnost jak jednoduchým způsobem kreslit základní grafická primitiva.</p>
<h3>OpenGL vrací úder</h3>
<p>Při pohledu du <em>Managed DirectX</em> dokumentace jsem se slzou v oku zavzpomínal na krásné časy s <em>glBegin</em>, <em>glEnd</em> a <em>glVertex</em> při programování grafického engine <a href="http://trionteam.net/projekt5410.php">Projektu 5410</a> a pokusil se spolu s Googlem najít způsob, jak spojit výhodu jednoduchého programování grafiky pomocí OpenGL s výhodou rychlého psaní kódu v C# (a samotřejmě s hotovými třídami pro kohonenovské sítě) a po chvíli hledání se zjevilo řešení téměř dokonalé &#8211; <a href="http://csgl.sourceforge.net/">CsGL</a>.</p>
<p>Podle seznamu novinek na webu knihovna už skoro třetím rokem není udržovaná, to ale nic nemění na její použitelnosti a užitečnosti. K dispozici programátorům dává kompletní rozhraní OpenGL 1.4 s vybranými rozšířeními (kompletní seznam podporovaných je <a href="http://csgl.sourceforge.net/extension-supported.txt" title="Seznam rozšíření podporovaných v CsGL">na webu</a>). Součástí jsou i funkce z GLU a vybrané funkce z GLUT.</p>
<h3>Objektově orientováno</h3>
<p>Protože OpenGL samo není objektové rozhraní, museli se autoři CsGL vyrovnat s přenosem na platformu, která naopak je na objekové orientovanosti založena. Samotné funkce <em>glXXX</em> zůstávají statické a jejich efekty se vážou vždy k aktuálnímu grafickému kontextu. I přes neobjektovost velké části rozhraní OpenGL se ale autorům podařilo několik samostatných tříd izolovat &#8211; především se jedná o grafický kontext reprezentující aktuální výstupní okno a o framework zjednodušující vytváření aplikací, který nahrazuje funkce pro práci s okenním systémem z GLUT.</p>
<p>Začlenění frameworku zajišťujícího vytvoření okna a vlastní smyčky zpráv do existující aplikace je skoro nemožné, proto jsem při práci ocenil spíše ovládací prvek <em>OpenGLControl</em>, který ve standardní třídě <em>Control</em> přidává možnost vykreslovat obsah ovládacího prvku pomocí funkcí CsGL místo obvyklého <em>System.Drawing</em>. Vytvoření komponenty zobrazující požadovanou trojrozměrnou neuronovou síť pak už bylo dílem okamžiku.</p>
<h3>Další vývoj</h3>
<p>Jak už jsem psal na začátku příspěvku, knihovna od poloviny roku 2003 není dále vyvýjena a udržována, to ale neznamená, že by se jednalo o slepou vývojovou cestu. Další vývoj totiž probíhá v rámci projeku <a href="http://www.mono-project.com">Mono</a>, kde je pod názvem <a href="http://www.mono-project.com/Tao">Tao</a> vytvářena komplexní knihovna pro vývoj her a multimediálních aplikací &#8211; kromě OpenGL ve verzi 1.5 jsou podporovány i další knihovny a API jako je OpenAL pro práci se zvukem, ODE pro fyziku pevných těles nebo vše sdružující platformově nezávislé SDL.</p>
<p>Narozdíl od CsGL se knihovna Tao snaží o maximální nezávislost na platformě, která může být výhodou, ale na druhou stranu z pochopitelných důvodů došlo k znatelnému nárůstu velikosti dll knihoven a potenciálnímu snížení výkonu. Proto pokud cílem je jednoduchá aplikace pro platformu Windows, která nepoužívá nejnovější funkce grafických akcelerátorů, je menší a specifičtěji zaměřené CsGL stále dobrou volbou.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ondrejsykora.com/blog/2006/04/21/3d-grafika-pro-net-snadno-a-rychle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

