Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

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.

Rejestracja funkcji

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 na serwerze

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 FunctionRegistry. Podczas rejestracji wyszukiwane są najpierw wszystkie klasy oznaczone adnotacją @Functions, następnie w tych klasach wyszukiwane są metody oznaczone adnotacją @Function 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 -> Function.

Rejestracja po stronie przeglądarki

Używanie stworzonej funkcji po stronie przeglądarki (na formularzu zadania) wymaga od programisty dostarczenia jej implementacji w języku JavaScript. Taka implementacja wykorzystywana jest podczas dynamicznych obliczeń po stronie przeglądarki klienta.

Funkcje rejestrowane są z wykorzystaniem API PW.fn.Functions (skrócona nazwa PW.Functions):

// funkcja "max" która zwraca obiekt typu "float" i przyjmuje 2 parametry typu "float"
PW.Functions.register("max", "float", ["float", "float"], function(value1, value2){
	return Math.max(value1, value2);
});
 
// funkcja "upper" która zwraca obiekt typu "string" i przyjmuje 1 parametry typu "string"
PW.Functions.register("i[[er", "float", ["float"], function(text){
	return text.toUpperCase();
});

Podczas rejestracji funkcji niezbędne jest zdefiniowanie:

  • nazwy (można zarejestrować wiele funkcji o tej samej nazwie ale musza mieć one inne typy parametrów)
  • typu zwracanej wartości
  • typów parametrów
  • implementacji funkcji

Tak zarejestrowana funkcja zostanie wywołana tylko dla wywołań z argumentami które będą pasowały do zdefiniowanych typów (albo będą tego samego typu albo mogą zostać przekonwertowane).

Oczywiście tak przygotowany skrypt musi zostać wstrzyknięty w obszar formularza zadania. Więcej o wstrzykiwaniu skryptów tutaj.

Funkcje ogólne

Jeżeli podczas rejestracji funkcji nie zdefiniujemy typów parametrów, to funkcja będzie traktowana jako implementacja ogólna. Taka implementacja zostaje wywołana jeżeli nie będzie żadnej innej implementacji funkcji, która może zostać wywołana z aktualnymi parametrami. Parametry przekazane do takiej funkcji są instancjami klasy PW.component.Arg.

// brak zdefiniowanych typów
PW.Functions.register("isVariable", "boolean", function(arg1){
	// arg1 jest obiektem klasy PW.component.Arg
	return !arg1.isArray && arg.value.is("variable");
});

Rejestracja we wtyczce

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" />

Taki wpis spowoduje automatyczne wyszukanie wszystkich zdefiniowanych funkcji.

Wykorzystanie funkcji po stronie przeglądarki

Obecnie funkcje mogą być wykorzystywane na formularzu zadania.

Pobranie funkcji odbywa się za pomocą obiektu PW.core.fn.Functions:

 var fn = Functions.getFunction("maxOf",[1,4]);

Mając pobraną funkcję z parametrami (PW.core.fn.Function) 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 83, 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]);
  • No labels