# Icallback

Definition: | include pGUI.e cbfunc res = Icallback(string name, integer rid = routine_id(name))) -- or -- cbfunc res = Icallback(integer rid) -- (see technicalia)
Description: | Utility function. Shorthand for call_back(routine_id(name)), but also validated as below.
pwa/p2js: | Supported. In practice it is a dummy function in pGUI.js, and p2js.exw converts Icallback("func") [phix] <==> Icallback(func); [js] There is as yet no cbfunc(), iup_name_from_cb() or iup_cb_from_name() [none of the ~200 examples in demo\rosetta or demo\pGUI use them]
Comments: | The routine name must be in scope, a literal string, and already defined at the point of use. pGUI records a list of all callbacks generated via Icallback() and validates all attempts to set callbacks against that list, since attempts to invoke something which is not a valid callback will always produce an indecipherable error message, or worse quietly terminate for no apparent reason, at least that is when said call is actually somewhere deep inside one of the precompiled IUP dynamic link libraries (which are written in C). The type cbfunc is used to validate that an atom address is (NULL or) the result of a previous call to Icallback(), alternatively you could just use the atom type. string name = iup_name_from_cb(atom addr) can also be used to retrieve the name corresponding to a valid (non-null previously generated) Icallback() address. You should not construct strings to pass to Icallback(), or rather the default for rid only works when name is a fixed literal string, so Icallback("quit_cb") is fine, but Icallback(name,routine_id(name)) is needed for variable names. The compiler issues a "missing parameters" compilation error when the latter is required. Alternatively the function cbfunc func = iup_cb_from_name(string name) can be used when needed, and declare constant <possibly_otherwise_unused>=Icallback("routine"), immediately following the actual definition of each and every routine that you might require this for. It returns null when unable to find a previously generated Icallback() of that name. It is entirely the programmer’s responsibility to only ever use this with application-wide unique names, any attempt to retrieve say "close_cb" will deliberately crash should there be, say, a dozen callbacks of that name scattered throughout the current application. When translating C code to Phix, a common requirement is to replace `(Icallback)xxx_cb` with `Icallback("xxx_cb")`. In 0.8.2 and later you can also use Icallback(xxx_cb), without the quotes, to exactly the same effect (see technicalia).
Example: |
    include pGUI.e

    function quit_cb()
        -- save_files() and/or IupConfigDialogClosed(config,dialog,"MainWindow"), etc.
        return IUP_CLOSE
    end function
    constant cb_quit = Icallback("quit_cb")

    Ihandle quit_btn = IupButton("Quit", cb_quit)
    --              or IupButton("Quit", Icallback("quit_cb")) [probably better if single use]
See Also: | Ihandle, IupButton, call_back, routine_id
Technicalia | There is in fact a secondary global function Icallbacki(integer rid) that the compiler quietly maps Icallback(integer rid) to, rather than raising an argument type mismatch error. That means that you can now code either Icallback("action_cb") or Icallback(action_cb), with the latter being automatically mapped for you, otherwise they behave in an entirely identical fashion (since 0.8.2). [Obviously the compiler will not flinch should you invoke Icallbacki() directly, or for that matter use routine_id("action_cb").] It does however coerce the interpreter into populating the symbol table with names (instead of ternary tree indexes), as explained in the documentation for get_routine_info().