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:
Any help debugging this issue would be greatly appreciated. Thanks!
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.
number
is internally handled as double (in GMS 3 at least)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)
}