About Monkey 2 › Forums › Monkey 2 Development › Can't use Color in Select/Case statement
This topic contains 6 replies, has 3 voices, and was last updated by
Mark Sibly
1 year, 7 months ago.
-
AuthorPosts
-
September 8, 2017 at 10:32 am #10344
Don’t know if this is a bug, or I just misunderstand how Select/Case works.
If I compare 2 Color objects with If, everything works.Monkey123Local currentColor:Color = Color.WhiteIf currentColor = Color.White then canvas.DrawText("Color is White",10,10)However, when making a comparison within a Select/Case, I get an error
Monkey123456789101112131415Select currentColorCase Color.White...`C:/Users/James/Monkey2-devel/monkey2/tmp/untitled1.buildv1.1.06/windows_debug/src/untitled1_untitled1.cpp:141:28: error: no match for 'operator==' (operand types are 't_std_graphics_Color' and 't_std_graphics_Color')if(this->m_currentColor==g_std_graphics_Color_White){~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~***** Fatal mx2cc error *****Internal mx2cc build errorSeptember 8, 2017 at 11:08 am #10346Because r/g/b/a components of Color is Float type, and Float is not comparable type.
Try to run these examples:
Monkey12345Local a:=3Local b:=5Local c:=-2If a-b=c Print "equals" ' workMonkey12345Local a:=0.3Local b:=0.5Local c:=-0.2If a-b=c Print "equals" ' doesn't work!September 8, 2017 at 3:08 pm #10348Your example has nothing to do with my problem. [b]If currentColor = Color.White [/b] works just fine. Succeeds when currentColor is white, fails on any other color. The problem is not with If/Then, but with Select/Case, which won’t even compile. Your example compiles fine, even though you don’t get the expected results.
Also, floats are comparable. The reason why your test fails is due to the tiny imprecision caused by storing floats. Due to that imprecision, they are rarely exactly equal. Instead, you should subtract the two and compare against a tolerance. If c-(a-b) < .001 gives the expected results in your example.
September 8, 2017 at 4:24 pm #10349Hmm. If we add operator <=> via extension, we get different error message
Monkey12345678Struct Color ExtensionOperator <=>:Int( other:Color)Return 0EndEndMonkey1234567891011121314C:/proj/monkey2/tmp/untitled2.buildv1.1.06/windows_debug/include/untitled2_untitled2.h: In function 'int bbCompare(const t_default_Test&, const t_default_Test&)':C:/proj/monkey2/tmp/untitled2.buildv1.1.06/windows_debug/include/untitled2_untitled2.h:94:86: error: passing 'const t_default_Test' as 'this' argument discards qualifiers [-fpermissive]inline int bbCompare(const t_default_Test&x,const t_default_Test&y){return x.m__cmp(y);}^C:/proj/monkey2/tmp/untitled2.buildv1.1.06/windows_debug/include/untitled2_untitled2.h:82:9: note: in call to 'bbInt t_default_Test::m__cmp(t_default_Test)'bbInt m__cmp(t_default_Test l_other);^Probably, something wrong in generated c++ code.
Other operators <> ,< , > , = don’t solve error.
September 8, 2017 at 4:29 pm #10350And the same problem have a place if we create other struct like color with comparison operators.
September 8, 2017 at 8:42 pm #10352I see the problem now. When the std.graphics.color module is compiled, an overloaded bbCompare() function is created. In this function, the fields are compared 1×1 and result is returned. This is what the If/Else/End statement is using to compare the two parameters. If I overload the = operator, a function called m_eq() is created and this is used instead of bbCompare.
Monkey2
Monkey12345If currentColor = Color.WhitePrint "Current color is white"ElsePrint "Current color is not white"End IfCompiles to C++
C++12345if((bbCompare(l_currentColor,g_std_graphics_Color_White)==0)){bb_print(bbString(L"Current color is white",22));}else{bb_print(bbString(L"Current color is not white",26));}Now the Select/Case statement is different. Instead of using bbCompare(), it is using C++’s built in == operator. Since Monkey2 has no way to overload C++’s == operator, it creates the error.
monkey2
Monkey12345678Select currentColorCase Color.WhitePrint "Select/Case Color is white"Case Color.RedPrint "Select/Case Color is Red"DefaultPrint "Select/Case Color is neither red nor white"End selectCompiles to C++
C++1234567if(l_currentColor==g_std_graphics_Color_White){bb_print(bbString(L"Select/Case Color is white",26));}else if(l_currentColor==g_std_graphics_Color_Red){bb_print(bbString(L"Select/Case Color is Red",24));}else{bb_print(bbString(L"Select/Case Color is neither red nor white",42));}So the solution would be either 1) Have Select/Case use bbCompare instead of == or 2) be able to override == at the C++ level.
September 9, 2017 at 3:58 am #10359It’s definitely a compiler bug, would you mind posting an issue at github?
-
AuthorPosts
You must be logged in to reply to this topic.