\chapter{UIML.NET} \section{Inleiding} Uiml.NET is een open source UIML renderer voor het .NET platform, geschreven in C\#. Het is ontwikkeld door Kris Luyten \footnote{kris.luyten@uhasselt.be} en Jo Vermeulen \footnote{jo.vermeulen@uhasselt.be}, beide werkzaam op het Expertise Centrum voor Digitale Media (EDM\footnote{http://www.edm.uhasselt.be}). In plaats van een UIML compiler werd er gekozen voor een UIML renderer. Dit is moeilijker en complexer, maar het is uiteindelijk meer flexibel. Wanneer het UIML document wordt gecompileerd, wordt het omgezet naar broncode, die op zijn beurt gecompileerd moet worden. Het transformeren van een UIML document in programma code heeft is enkel voordelig wanneer de code naderhand nog moet worden aangepast. Het renderen daarentegen is meer flexibel omdat je zo vlug een prototype kan maken dat direct getest kan worden. Bovendien biedt het dynamische veranderingen aan in de UI en een transparant mechanisme voor het connecteren van de gerenderde UI en de applicatie logica\cite{open_uiml_renderer}. De renderer zal de UIML code die in het document staat interpreteren en enkel tonen op het scherm indien deze aan de regels van een geldig UIML document voldoet. \section{Architectuur\cite{generic_approach}} Het renderen van een UIML document gebeurt in drie stappen: pre-processing, main processing en post-processing. \begin{description} \item[Pre-processing] Tijdens deze stap zal een UIML document worden omgevormd tot een ander UIML document. Enkele voorbeelden zijn het toepassen van layout beperkingen en aanpassing aan een gebruikersprofiel. \item[Main processing] Tijdens deze stap wordt het UIML document ge\"interpreteerd en wordt een concrete instantie opgebouwd als een boomstructuur met de beschikbare widget set. \item[Post-processing] Tijdens deze stap wordt de concrete instantie die aangemaakt is tijdens de main processing gemanipuleerd. Een voorbeeld hiervan is het binden van de UI met de applicatie logica. \end{description} We zijn vooral ge\"interesseerd in main processing. Hierin wordt de concrete instantie opgebouwd. Dit gebeurt in vijf stappen: \begin{enumerate} \item De UIML renderer neemt een UIML document als input, en zoekt de correcte rendering backend bibliotheek waar in het UIML document naar verwezen wordt \item Een interne representatie van het UIML document wordt opgebouwd. Ieder \texttt{part} element van het document wordt verwerkt om een boom van abstracte interface componenten op te bouwen. \item Voor ieder \texttt{part} element wordt de overeenkomstige \texttt{style} toegepast die in het document staat. \item Voor ieder \texttt{part} element wordt het overeenkomstige gedrag (\texttt{behavior}) gekoppeld en de vereiste bibliotheken voor het gedrag worden \textit{just-in-time} geladen. \item De gegenereerde boom wordt overgedragen aan de rendering module. Voor ieder \texttt{part} element wordt een overeenkomstig concreet widget geladen volgens de mapping die gedefinieerd is in de vocabulaire en wordt gelinkt met de interne respresentatie. Voor het gegenereerde concrete widget worden de gerelateerde style eigenschappen opgehaald en gemapt door de vocabulaire naar concrete widget eigenschappen. Hierna worden ze toegepast op het concrete widget. \end{enumerate} In stap 4 wordt ieder \texttt{part} element gekoppeld met zijn overeenkomstige gedrag. Dit gebeurt via reflectie. De rendering engine weet namelijk niet wat de concrete widgets zijn. Het enige dat ter beschikking is, is de vocabulaire. Door het gebruik van reflectie kunnen we instanties van klasses aanmaken door enkel het kennen van de naam. Indien reflectie niet gebruikt zou worden, hebben we een ad-hoc mapping nodig. Dit limiteert de rekbaarheid van de UIML vocabulaire, als een nieuwe mapping in de vocabulaire wordt ingevoegd, zou de volledige kern ge\"update moeten worden. Dit is niet nodig met reflectie. \section{Backends} UIML.NET bevat \'e\'en rendering kern, maar meerdere rendering backends. Momenteel worden volgende backends ondersteund: \begin{itemize} \item System.Windows.Forms \item Compact SWF \item GTK\# \item Wx.net (klein deel) \item Qt\# (klein deel) \end{itemize} De backends hebben een beperkte rol. Zij verwerken enkel dingen die speciefiek zijn voor een bepaalde widget set. De rest wordt allemaal afgehandeld in de kern. \section{Huidige implementatie van condities} \label{huidige_impl} Momenteel wordt enkel het \texttt{$<$event$>$} element ondersteund voor condities. Dit element laat toe een bepaald event te koppelen aan een widget. Na het plaatsvinden van dit event wordt de bijhorende actie opgeroepen. Als voorbeeld kunnen we een knop nemen. Aan deze knop kan een event \texttt{`ButtonClicked'} worden gekoppeld. De koppeling gebeurt volledig via reflectie. Wanneer een event gelinkt moet worden, wordt er een delegate aangemaakt die een functie bevat die wordt opgeroepen wanneer het event plaatsvindt. Een delegate kan vergeleken worden met een functie pointer in C of C++. Het biedt de mogelijkheid om extra parameters in een functie te encapsuleren. Een delegate is een `closure', het heeft toegang tot de omliggende variabelen en functies. Een voorbeeld is te zien in listing \ref{delegate_ex}. We zien hier dat de statische functie \texttt{Display} wordt gekoppeld aan de delegate \texttt{Print}. Als we dan de regel \texttt{p("Hallo wereld!");} uitvoeren, wordt de functie \texttt{Display} aangeroepen met als parameter \texttt{"Hallo wereld!"}. Deze wordt dan in de console weergegeven. \lstset{basicstyle=\footnotesize, frameround=fttt, numbers=left, numberstyle=\tiny, language=[Sharp]C, breaklines=true} \begin{lstlisting}[float, frame=bt, caption=Delegate Voorbeeld, label=delegate_ex] using System; delegate void Print(string s); class Foo { static void Display(string s) { Console.WriteLine(s); } public static void Main() { Print p = Display; p("Hallo wereld!"); } } \end{lstlisting} Iedere backend heeft zijn eigen implementatie voor het linken van de events. Een schematische voorstelling van de huidige implementatie is te vinden in de figuur \ref{huidige_impl_events}. Als er op een knop geklikt wordt, dan zal de functie \texttt{Execute} worden aangeroepen die via een delegate is gekoppeld. Deze functie zorgt er dan voor dat de bijhorende actie wordt uitgevoerd. \begin{figure}[h] \center \includegraphics[scale=1]{images/events_huidige_impl.jpg} \caption{Werking van een gekoppelde delegate} \label{huidige_impl_events} \end{figure} Het \texttt{$<$event$>$} element is niet het enige element dat in een conditie kan voorkomen. Zo hebben we ook nog \texttt{$<$equal$>$} en \texttt{$<$op$>$} (zie sectie \ref{conditions}). Deze elementen worden echter nog niet ondersteund door de huidige implementatie van UIML.NET.