Funkcje ułatwiają wykonywanie często wykonywanych operacji, takich jak np. sumowanie wartości. Zapobiega to wielokrotnej duplikacji kodu. Funkcje powinny być niezależne oraz jak najbardziej ogólne i elastyczne (możliwość wykorzystania ich w jak największej liczbie przypadków).
System pozwala na rejestrowanie i wykorzystywanie predefiniowanych funkcji zarówno po stronie serwera jak i po stronie przeglądarki.
Funkcja musi zawsze być zarejestrowana po stronie serwera oraz może dodatkowo być zarejestrowana po stronie przeglądarki, gdy chcemy, aby była też tam wykorzystywana. |
Rejestracja funkcji dostępnych w systemie odbywa się podczas uruchomienia systemu oraz dynamicznie dla dynamicznych zasobów, takich jak wtyczki. Za rejestrację i przechowywanie funkcji odpowiada . Podczas rejestracji wyszukiwane są najpierw wszystkie klasy oznaczone adnotacją @
, następnie w tych klasach wyszukiwane są metody oznaczone adnotacją @
i zostają one zarejestrowane jako funkcje.
Poniższy przykład przedstawia definicję prostej funkcji zwracającej wartość wyższej liczby.
@Functions public class BasicFunctions { @Function public Integer maxOf( Integer a, Integer b ) { return Math.max( a, b ); } } |
Zarejestrowana funkcja posiada nazwę, zwracany typ oraz definicję parametrów -> .
Po stronie przeglądarki musimy sami zarejestrować funkcję. W tym celu należy wywołać metodę register z
Functions.register({ name: "maxOf", fn: function(value1, value2) { return Math.max(value1, value2); }, parameterTypes: ["float", FloatType] }); |
W tym przypadku zarejestrowaliśmy funkcję o nazwie maxOf z implementacją przekazaną we właściwości fn.
Właściwość parameterTypes jest opcjonalna, jednak w większości przypadków powinna być uzupełniana. Określa ona typy parametrów funkcji, dzięki czemu podczas wywoływania funkcji podane wartości parametrów są konwertowane do tych typów. Parametry podajemy w takiej samej kolejności jak występują one w funkcji. Parametry możemy podać jako klucz typu (float), lub jako obiekt typu (FloatType). Jeżeli funkcja zostanie wywołana z większą ilością parametrów niż ilość zdefiniowanych typów, to wszystkie dodatkowe parametry zostaną przekonwertowane do typu, który jest ostatni w tablicy.
Należy pamiętać, że każda funkcja zarejestrowana po stronie przeglądarki musi mieć swój odpowiednik po stronie serwera. |
Rejestracja funkcji we wtyczce jest taka sama jak zostało to opisane powyżej, jednak należy dodatkowo zaznaczyć, że wtyczka ta udostępnia funkcje do zarejestrowania. W tym celu należy w pliku suncode-plugin.xml dodać wpis:
<functions key="functions" /> |
Jest to wymagane, aby nie trzeba było przeszukiwac wszystkich uruchomionych wtyczek, tylko te, które faktycznie posiadają funkcje.
Obecnie funkcje mogą być wykorzystywane na formularzu zadania.
Pobranie funkcji odbywa się za pomocą obiektu :
var fn = Functions.getFunction("maxOf",[1,4]); |
Mając pobraną funkcję z parametrami () możemy ją wywołać:
fn.call(); //returns 4; |
W powyższym przykładzie pobrania funkcji, parametry zostały podane w sposób uproszczony, czyli same wartości bez konkretnego typu. Podczas konwersji typów, mechanizm sam zgadnie typy tych wartości. Gdyby została tam podana wartość tekstowa np.: "zmienna_1", to zostałoby to rozpoznane jako typ string. Jednak w przypadku, gdybyśmy chcieli, aby w tym miejscu znalazła się wartość zmiennej formularzowej o id zmienna_1, to w takim przypadku trzeba podać wartość razem z typem:
var fn = Functions.getFunction("maxOf",[{type: "variable",value: "zmienna_1"}, 4]); //lub var fn = Functions.getFunction("maxOf",[ServiceFactory.getVariableService().get("zmienna_1"), 4]); |
Istnieje również możliwość podania innej funkcji w parametrze:
var fn = Functions.getFunction('maxOf',[{type:"function",value:{name:"maxOf",parameters:[{type:"float",value:8},{type:"float",value:4}]}} ,3]); |
W powyższym przykładzie najpierw zostanie wywołana wewnętrzna funkcja maxOf z parametrami 8 i 4, która zwróci wynik 8 i następnie zostanie wywołana funkcja zewnętrzna maxOf z parametrami 8 i 3, która zwróci wynik 3. Wydaje się jednak, że prostszym i "czystszym" rozwiązaniem jest wywołanie samemu wewnętrznej funkcji:
var fn = Functions.getFunction('maxOf',[Functions.getFunction('maxOf',[8,4]),3]); |