The reason I'm trying to use a mostly channel-based interface rather than a function- and method-based interface is because functions block, and if they don't block then they can have their executions reordered. If you take safeguards against either of these things happening, then you're really just wrapping a channel operation under the hood!
For the moment, at least, I really want all communication between blocks, foundations etc, to happen on non-blocking channels.
There are three major ways to have non-blocking channels. At least three that I'm thinking about right now.
1) Infinitely buffered channels: there is a goroutine gobetween keeping track of everything.
2) Drop-channels: a channel with a finite buffer, but when the buffer is full a send is simply ignored rather than blocked.
The idea is that some components might stall out for whatever reason, and we don't want to have that become a memory leak. If they somehow eventually wake up, then emptying the current buffer will enable them to get no messages.
3) Stacked channels: a channel that combines all unreceived sends into a single message.
An example of this is the message sent by a block to its parent to composite the buffer. The parent only really needs to know about the most recent buffer, so sending a buffer should cause the buffer already in there to be dropped. Another example is the Redraw channel, which informs a block that some portion of its buffer needs to be redrawn. The sends are combined into a single message that describes the union of all the previous messages, so the block redraws only once.
The result of having things work like this is that the api looks like a list of channels instead of a set of functions. It's less efficient than method calls, especially when a goroutine switch is required. Fortunately this is a UI kit, and performance faster than a certain mark is pointless: a human won't be able to tell the difference after a while.
What a human *can* notice is when a hitch in one component brings down the whole UI. That is what we're trying to avoid here. The goal is to make it so that a properly written component cannot be adversely affected by another component unless it's a child or a parent. Siblings can't affect each other as long as the parent is written properly.
One thing that's getting me down a bit here is the lack of generics. I'd really like to have typed channels, but that means a lot of specialty code. Might be better to just require type assertions. Anyone have an opinion on that?
--
You received this message because you are subscribed to the Google Groups "go-uik" group.
To post to this group, send email to
go-...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "go-uik" group.
To post to this group, send email to go-...@googlegroups.com.