1. Phix object arrays
- Posted by irv Feb 03, 2021
- 780 views
Often it is useful to declare an array of objects; buttons for example, rather than do them individually:
include GtkWindow.e include GtkBox.e include GtkButton.e Window win = new() win.border_width = 10 win.connect("destroy","Quit") Box pan = new() win.add(pan) sequence buttons = repeat(0,5) for i = 1 to length(buttons) do buttons[i] = new(Button) pan.add(buttons[i]) end for buttons[1].label = "One" -- can't do this! buttons[3].sensitive = false -- can't do this either! win.show_all() gtk_main()
/home/irv/pgtk/buttontest.ex:18 buttons[1].label = "One" ^ '=' expectedIt is often necessary to call a method for one or more of the items in the array, but as noted above, can't do that. button.label and button.sensitive are valid for individually declared objects, but not for one picked from a sequence of objects. IOW, subscripts don't work here.
Is there another way?
2. Re: Phix object arrays
- Posted by petelomax Feb 03, 2021
- 835 views
/home/irv/pgtk/buttontest.ex:18 buttons[1].label = "One" ^ '=' expectedIt is often necessary to call a method for one or more of the items in the array, but as noted above, can't do that.
Is there another way?
The compiler needs a type hint, for example
Button b = buttons[1] b.label = "One"
or maybe (you could also use a generic struct b parameter here)
procedure set_label(Button b, string label) b.label = label end procedure set_label(buttons[1],"One")
Unfortunately it's just not smart enough to figure out that buttons[1] is a Button instance, not entirely dissimilar to
Button b = new() -- ok -- buttons[i] = new() -- not ok buttons[i] = new(Button) -- ok
In fact, I'll go so far as to recommend this version of your above for loop (one more line, but also one less subscript):
for i = 1 to length(buttons) do Button b = new() buttons[i] = b pan.add(b) end for
3. Re: Phix object arrays
- Posted by irv Feb 03, 2021
- 784 views
Unfortunately it's just not smart enough to figure out that buttons[1] is a Button instance, not entirely dissimilar to how you can code
Button b = new()
but you had to say
buttons[i] = new(Button)
rather than
buttons[i] = new()
I was afraid that might be the case. Let me think about the best way to work around this. In EuGTK, it is very convenient to be able to make calls like this by name:
set("Button1.label","Foo")
Perhaps I can do something similar.
4. Re: Phix object arrays
- Posted by petelomax Feb 03, 2021
- 765 views
Of course C++ and friends use explicit casts for this kind of stuff.
Thinking out loud here, internally the compiler proper is (kind of) actually smart enough to utilise say
function toButton(Button b) return b end function
However the interpreter and the main parser/front end, probably not (yet)... so thats maybe somewhere between 22% and 23% of a whole idea.
5. Re: Phix object arrays
- Posted by petelomax Feb 03, 2021
- 777 views
In EuGTK, it is very convenient to be able to make calls like this by name:
set("Button1.label","Foo")
Perhaps I can do something similar.
This should work:
procedure set(struct s, string field, object v) s[field] = v end procedure set(buttons[1],"label","Foo")
6. Re: Phix object arrays
- Posted by irv Feb 03, 2021
- 770 views
procedure set(struct s, string field, object v) s[field] = v end procedure set(buttons[1],"label","Foo")
Yes, something like that should work. I'm trying for as much consistency and simplicity as possible. Phix offers simpler syntax than EuGTK allows, in most cases.
7. Re: Phix object arrays
- Posted by irv Feb 03, 2021
- 874 views
- Last edited Feb 04, 2021
Simplest solution seems to be to forget making an array, and just name the items.
include GtkWindow.e include GtkBox.e include GtkButton.e Window win = new() win.border_width = 10 win.connect("destroy","Quit") Box pan = new() win.add(pan) for i = 1 to 5 do Button x = new() x.label = sprintf("Button %d",i) x.name = sprintf("B%d",i) -- name 'em. x.connect("clicked","Toggle") -- any button click calls Toggle() pan.add(x) end for win.show_all() gtk_main() public function Toggle() Object y = from_name("B2") -- retrieve by name, -- some various ways to toggle: y.sensitive = not y.sensitive --[A] works -- Warning sq_not assumed y.sensitive = not(y.sensitive) --[B] works -- same warning y.sensitive = (y.sensitive = 0) --[C] works -- no warning, but awkward y.sensitive = sq_not(y.sensitive) --[D] works -- no warning, strange syntax -- What am I missing here? -- Shouldn't [A] or [B], the most "normal" syntax, -- be the default and not issue a warning? -- After all, y.sensitive is not a sequence, it is a boolean, -- so assuming that it needs a sequence operation is wrong somehow. return 1 end function
Further testing proves that this method works OK for buttons, because there are rarely going to be more than a few. For menus, it requires far too much work, too many lines of code. It's going to be necessary to find a way to use arrays of widgets in some manner. Perhaps a WidgetArray class?
8. Re: Phix object arrays
- Posted by petelomax Feb 04, 2021
- 724 views
-- some various ways to toggle: y.sensitive = not y.sensitive --[A] works -- Warning sq_not assumed y.sensitive = not(y.sensitive) --[B] works -- same warning y.sensitive = (y.sensitive = 0) --[C] works -- no warning, but awkward y.sensitive = sq_not(y.sensitive) --[D] works -- no warning, strange syntax -- What am I missing here? -- Shouldn't [A] or [B], the most "normal" syntax, -- be the default and not issue a warning? -- After all, y.sensitive is not a sequence, it is a boolean, -- so assuming that it needs a sequence operation is wrong somehow.
I get no warning when it is a bool, but I do get a warning when it is string/sequence.
However, user defined types inside classes were completely broken, I fixed that just yesterday, totally independently of this, so this may or may not help: pmain.e line 11687
--4/2/21... -- tN = addUnnamedConstant(Typ,T_integer) if Typ>T_object then tN = addRoutineId(Typ) else tN = addUnnamedConstant(Typ,T_integer) end if
Since boolean is actually a user defined type whereas bool is builtin, that might have been causing it (and I can no longer test that theory here).
9. Re: Phix object arrays
- Posted by irv Feb 05, 2021
- 640 views
We must have different copies of pmain.e, or the line # is wrong.
11683 if tid!=0 then 11684 tid = srids[tid] 11685 else 11686 if tN=0 then tN = addUnnamedConstant(Typ,T_integer) end if 11687 tid = tN 11688 end if 11689 PushFactor(tid,true,T_integer) 11690 PushFactor(vN,true,T_integer) 11691 getToken()
Found a likely call a bit earlier:
11654 integer Typ = tokno, 11655 --5/11/2020: 11656 -- tN = addUnnamedConstant(Typ,T_integer) 11657 tN = 0 11658 while true do 11659 getToken() 11660 if toktype!=LETTER or ttidx=T_end then
Is 11656 the right place to insert the fix?
10. Re: Phix object arrays
- Posted by petelomax Feb 05, 2021
- 633 views
We must have different copies of pmain.e, or the line # is wrong.
11686 if tN=0 then tN = addUnnamedConstant(Typ,T_integer) end if
Found a likely call a bit earlier: Is 11656 the right place to insert the fix?
No, I must have split your line 11686, then made that change.
Yeah, I must have changed about 20 things in my pmain.e since 0.8.3 was released 3 days ago.