if ((Player getVariable "SpareTime") > 0) then {...
« Changelog 24/06/2009Download »

New to ArmA 2: (ui)Namespace

Permalink 06/21/09 02:39, by jonas, Categories: ArmA

BIS introduced some namespaces in ArmA II. What is a namespace?

In general, a namespace is an abstract container providing context for the items (names, or technical terms, or words) it holds and allowing disambiguation of items having the same name (residing in different namespaces).

From Wikipedia

Short: ArmA II doesn't give us the hole concept of namespaces. We still need to use our OPFEC tags to ensure that we don't overwrite other variables.

But why do we have namespace in A2?

BIS enforces us to use uiNamespace when working with controls.

...

From our current knowledge: This is required for correctly working saves.

First all small introduction how to work with namespaces:
We can use getVariable and setVariable to access elements of the namespace.

Code:


uiNameSpace setVariable ["ION_DSM2_Display_ShowModal", findDisplay _display];
uiNameSpace getVariable "ION_DSM2_Display_ShowModal"

Luckily this ain't the only commands, we also have with:

Code:


with uiNameSpace do {
  ION_DSM2_Ctrl_ShowModal = ION_DSM2_Display_ShowModal displayCtrl (_x select 0);
  ION_DSM2_Ctrl_ShowModal ctrlShow false;
};

What does with do:
All global variables within the code block are taken out of the namespace, whereas the local variables remain as usual.

So what are we required to do when porting older code to A2?

We can't save ui variables (like controls or displays) in local or global variables any more. We need to save them to uiNamespace instead. This is not that hard since we can use with:

Code:


_disp = findDisplay _display;
{
  _ctrl = _disp displayCtrl (_x select 0);
  _ctrl ctrlShow false;
};

Code:


with uiNameSpace do {
  ION_DSM_Test_Ctrl_ShowModal = ION_DSM_Test_Display_ShowModal displayCtrl (_x select 0);
  ION_DSM_Test_Ctrl_ShowModal ctrlShow false;
};

Not really hard. But we have a few downsides:

  • We can't use global variables from the missionNamespace (the default namespace) within the with block, so we need to use getVariable or a local variable instead:

    Code:


    ((uiNameSpace getVariable "ION_RTE_Display") displayCtrl ION_CREATEMARKER_ICON_2) lbSetCurSel (ION_RTE_CFG_Marker_CFG find (_data select 1));
  • We can't iterate with forEach over control items. This doesn't work since a uiNameSpace variable would get stored within a local variable _x.
    This is solvable via iterating over the idcs of the controls.

Ok, I'll use with uiNamespace and everything will be fine!

Yes, in general this may be true. But there are still some questions open:

  • Why does BIS implemented them exactly?
  • Why is this concept broken? Eventhandler will transfer controls/displays within the local _this variable instead of using the uiNameSpace
  • Since the script engine can detect when ever a user puts control in missionNamespace, why can't it move it automatically to uiNamespace. Because of possible name conflicts?

What's about uiNamespace and the RTE?

It was a little pain, but I converted all my scripts to uiNamespace. All my scripts?
Sadly no, a bug in A2 prevents me from using uiNamespace everywhere.
I need to fall back to the pre-a2-style in larger scripts which will break the 3ms limit.

How do I manage this?

We have disableSerialization which disables uiNamespace within this script. BIS implemented uiNamespace for a reason, so it may not be a could idea to ignore it and use disableSerialization instead. But as long as uiNamespace is bugged, I don't have any chance...

No feedback yet