0

I'm trying to enforce a value threshold on a realfield input widget in DM-script such that valid values are between 0 and 0.05. When I input 0.06 and click outside the widget, it warns that the value is invalid and resets to the previous value. However, when I input 0.05, no warning is triggered. Then, if I try entering any other value afterward, I get an error stating "Wrong config file."

Below is a simplified version of my code:

Number get_tag_as_number(TagGroup tg, String tag_path, String tag_type, Number low_limit, Number high_limit)
{
    Number tag_value, tag_is_valid
    if (tag_type == "Boolean") tag_is_valid = tg.TagGroupGetTagAsBoolean(tag_path, tag_value)
    if (tag_type == "Number") tag_is_valid = tg.TagGroupGetTagAsNumber(tag_path, tag_value)
    if (!tag_is_valid)
    {
        Result("ERROR: Can not get tag value of " + tag_path + ".\n")
        ShowAlert("Can not get tag value of " + tag_path + ".", 0)
        Exit(0)
    }

    if (tag_value < low_limit || tag_value > high_limit)
    {
        Result("ERROR: Wrong config file, " + tag_path + ".\n")
        ShowAlert("Wrong config file, " + tag_path + ".", 0)
        Exit(0)
    }
    return tag_value
}

Class testUI : UIFrame
{
    TagGroup ui_config_tg
    Void tg_init(Object self)
    {
        ui_config_tg = NewTagGroup()
        ui_config_tg.TagGroupSetTagAsFloat("display_font:init_value", 0.015)
    }
    TagGroup create_realfield_widget(Object self)
    {
        Number low_limit = 0
        Number high_limit = 0.05
        Number init_value = get_tag_as_number(ui_config_tg, "display_font:init_value", "Number", low_limit, high_limit)
        TagGroup realfield_widget
        realfield_widget = DLGCreateRealField(init_value, 16, 3, "action")
        realfield_widget.DLGIdentifier("#realfield_widget")
        return realfield_widget
    }
    Void action(Object self, TagGroup item_tag)
    {
        Number low_limit = 0
        Number high_limit = 0.05
        Number curr_value = item_tag.DLGGetValue()
        Number init_value = get_tag_as_number(ui_config_tg, "display_font:init_value", "Number", low_limit, high_limit)
        
        if (curr_value < low_limit || curr_value > high_limit)
        {
            OKDialog("Font size must between " + low_limit + " to " + high_limit)
            self.LookUpElement("#realfield_widget").DLGValue(init_value)
            item_tag.DLGValue(init_value)
            Exit(0)
        }
        ui_config_tg.TagGroupSetTagAsFloat("display_font:init_value", curr_value)
        Result(curr_value)
    }
    
    TagGroup create_dialog(Object self)
    {
        self.tg_init()
        TagGroup realfield_widget = self.create_realfield_widget()        
        TagGroup tabs = DLGCreateTabList()
        tabs.DLGAddElement(realfield_widget)
        TagGroup dialog = DLGCreateDialog("test")
        dialog.DLGAddElement(tabs)
        return dialog
    }
    
    testUI(Object self)
    {
        self.init(self.create_dialog())
        self.Display("test")
    }
}

Alloc(testUI)

Questions:

  1. Why does the widget behave correctly (warning on 0.06) but not on 0.05, even though 0.05 is the upper boundary?
  2. Is there a potential logic error in my threshold validation that could be causing the "Wrong config file" error on subsequent inputs?
  3. Has anyone encountered similar issues with DM-script's realfield widget or threshold checks?

Any help debugging this issue would be greatly appreciated. Thanks!

1 Answer 1

1

The logic is fine, but you are running into rounding issues which are particularly hard to spot on scripting languages with automatic number & string conversions.

  • DM-Script numberis internally handled as double (in GMS 3 at least)
  • When you write the value to tags as float you loose precision.

It is saver to stick with ...asNumber to avoid these issues. You need to be type specific only in cases where it matters, like streaming to a binary stream.

See the following example

number tag_value = 0.05
number low_limit = 0
number high_limit = 0.05

clearresults()
Result("\n Limits are (double):")
result("\n: low limit:  "+low_limit)
result("\n: high limit: "+high_limit)

Result("\n Tag value is (double):")
result("\n tag value:  "+Format(tag_value,"%20.12f"))
Result("\n (tag_value - low_limit) : "+(tag_value - low_limit))
Result("\n (tag_value - high_limit): "+(tag_value - high_limit))

taggroup tg = newTagGroup()

tg.TagGroupSetTagAsNumber("Test",tag_value)
tg.TagGroupGetTagAsNumber("Test",tag_value)

Result("\n ~~~~~ Now with Tag read & write as NUMBER (internally this is DOUBLE)")
result("\n tag value:  "+Format(tag_value,"%20.12f"))
Result("\n (tag_value - low_limit) : "+(tag_value - low_limit))
Result("\n (tag_value - high_limit): "+(tag_value - high_limit))

tg.TagGroupSetTagAsDouble("Test",tag_value)
tg.TagGroupGetTagAsDouble("Test",tag_value)

Result("\n ~~~~~ Now with Tag read & write as DOUBLE")
result("\n tag value:  "+Format(tag_value,"%20.12f"))
Result("\n (tag_value - low_limit) : "+(tag_value - low_limit))
Result("\n (tag_value - high_limit): "+(tag_value - high_limit))

tg.TagGroupSetTagAsFloat("Test",tag_value)
tg.TagGroupGetTagAsFloat("Test",tag_value)

Result("\n ~~~~~ Now with Tag read & write as FLOAT")
result("\n tag value:  "+Format(tag_value,"%20.12f"))
Result("\n (tag_value - low_limit) : "+(tag_value - low_limit))
Result("\n (tag_value - high_limit): "+(tag_value - high_limit))

Alternatively, you can fix your script by not checking against "0" exactly, but a against a small epsilon value that accounts for the precision problem:

[...]
    number eps = 1e-9
    if ((tag_value - low_limit)< eps || (tag_value - high_limit) > eps)
    {
        Result("ERROR: Wrong config file, " + tag_path + "." + "\n")
        ShowAlert("Wrong config file, " + tag_path + ".", 0)
        Exit(0)
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.