Your Digital Media Has Never Looked So Good

 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

fake Modal Menu with getMessagePort()

Thu Apr 02, 2015 3:13 pm

In trying to roll my own Modal pop-up menu, I quickly ( it's all relative! )
learned that I can't have a Modal anything! My app needs to keep doing
stuff even when menus and such are on screen awaiting user input.

So, in using getMessagePort() to hijack my main event loop, it crossed my
mind that I could send other "doEvent()/Update()" functions as parameters
into my Fake-Modal Menu of Awesomeness.

Q: As much as the possibility of this working is intriguing, how often is
such a construct put into action? Is this a standard way of doing such
a thing? If not, why have a getMessagePort() at all?

Follow-up Q: Are easing animations typically modal as well? Who here has
implemented non-modal transition animations?

Thanks in advance.

peace & 42
 
Rek
Posts: 97
Joined: Mon Jul 08, 2013 9:22 am

Re: fake Modal Menu with getMessagePort()

Thu Apr 02, 2015 3:17 pm

dev42 wrote:
In trying to roll my own Modal pop-up menu, I quickly ( it's all relative! )
learned that I can't have a Modal anything! My app needs to keep doing
stuff even when menus and such are on screen awaiting user input.

So, in using getMessagePort() to hijack my main event loop, it crossed my
mind that I could send other "doEvent()/Update()" functions as parameters
into my Fake-Modal Menu of Awesomeness.

Q: As much as the possibility of this working is intriguing, how often is
such a construct put into action? Is this a standard way of doing such
a thing? If not, why have a getMessagePort() at all?

Follow-up Q: Are easing animations typically modal as well? Who here has
implemented non-modal transition animations?

Thanks in advance.

peace & 42


Are you using the 2D api for this?
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Thu Apr 02, 2015 3:22 pm

Rek wrote:
Are you using the 2D api for this?

Yes.
 
User avatar
NewManLiving
Posts: 452
Joined: Fri Aug 02, 2013 6:14 pm

Re: fake Modal Menu with getMessagePort()

Thu Apr 02, 2015 4:49 pm

just pass control to a message loop in your modal dialog. Use getmessage instead of wait or waitmessage
My Channels: 2D API Framework Presentation: https://owner.roku.com/add/2M9LCVC
Updated: 11-11-2015 - Completed Keyboard interface
The Joel Channel ( Final Beta )
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Thu Apr 02, 2015 11:13 pm

NewManLiving wrote:
just pass control to a message loop in your modal dialog. Use getmessage instead of wait or waitmessage

could you expound on this a bit? What exactly do you mean by "pass control"? :oops: :?:
 
User avatar
NewManLiving
Posts: 452
Joined: Fri Aug 02, 2013 6:14 pm

Re: fake Modal Menu with getMessagePort()

Fri Apr 03, 2015 3:52 am

When you create your dialog you first draw it and then go into another message loop. But you do not use wait. Instead you use getmessage which returns immediately if there's no button pressed. it just returns invalid. So if you have to keep processing something you can continue until you notice some valid input. Of course what you are doing should not block the message queue either. If You have to block the queue then you don't even need a loop. What is it that you are trying to do?
My Channels: 2D API Framework Presentation: https://owner.roku.com/add/2M9LCVC
Updated: 11-11-2015 - Completed Keyboard interface
The Joel Channel ( Final Beta )
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Mon Apr 06, 2015 10:05 pm

NewManLiving wrote:
What is it that you are trying to do?

Code better? :wink: That really isn't a joke! I've apparently coded myself into a corner. I've been working on a game loop "framework" that I could use in the future and not just on the app I'm currently working on. One "feature" of this framework was that I allowed more than one object to process button events. Not only that, but some objects, depending on which button was pressed, could pass which button was pressed on to the next object in the list... or not.

To facilitate all of this, I started accumulating a bunch of boolean flags: .isVisible, .hasFocus, .isModal

Now I'm not saying I was completely wrong ( why would any programmer *ever* say that?! ), but I'm starting to see that I really was over-complicating things.

NewManLiving wrote:
another message loop

That's just it. I only had one loop. This is new territory for me. I'm currently working through the 7 Stages of Learning to Program Better ( aka Programming Grief ). I initially posted when at the first stage, Shock & Denial. I won't go into the other stages as I don't want to cause anybody undue stress revisiting their past programming learning journeys. :wink:

NewManLiving wrote:
What is it that you are trying to do?

Topically? errr to learn if implementing more than one event loop is the way to go.
 
Rek
Posts: 97
Joined: Mon Jul 08, 2013 9:22 am

Re: fake Modal Menu with getMessagePort()

Tue Apr 07, 2015 12:54 pm

dev42 wrote:
NewManLiving wrote:
What is it that you are trying to do?

Code better? :wink: That really isn't a joke! I've apparently coded myself into a corner. I've been working on a game loop "framework" that I could use in the future and not just on the app I'm currently working on. One "feature" of this framework was that I allowed more than one object to process button events. Not only that, but some objects, depending on which button was pressed, could pass which button was pressed on to the next object in the list... or not.

To facilitate all of this, I started accumulating a bunch of boolean flags: .isVisible, .hasFocus, .isModal

Now I'm not saying I was completely wrong ( why would any programmer *ever* say that?! ), but I'm starting to see that I really was over-complicating things.

NewManLiving wrote:
another message loop

That's just it. I only had one loop. This is new territory for me. I'm currently working through the 7 Stages of Learning to Program Better ( aka Programming Grief ). I initially posted when at the first stage, Shock & Denial. I won't go into the other stages as I don't want to cause anybody undue stress revisiting their past programming learning journeys. :wink:

NewManLiving wrote:
What is it that you are trying to do?

Topically? errr to learn if implementing more than one event loop is the way to go.


We only use 1 run-loop in our app. The key is to arrange components in a hierarchy and allow them to register with their parents as event receivers. Whenever an event is pulled out of the message port in the main loop, send it to the root component. Each component then either handles the event, or forwards it to it's children, who can also handle, or forward it. Here's some pseudo code:

**Disclaimer** This was all typed directly into the forum... It might not compile/run, but should demonstrate the concept
   ' -----------------------------------------------
   ' Entry: Main
   function main() as Void
      runloop = runloopCreate()
   
     ' Create a button
     button = buttonCreate()
     button.setText("Click Me!") ' setText not included in example
   
     ' Add button
     runloop.getRoot().addChild(button)

     ' Execute
     runloop.run()
   end function

   ' -----------------------------------------------
   ' Class: Component

   function componentCreate() as Object
      return {
         handleEvent               : _component_handleEvent
         handleOrForwardEvent: _component_handleOrForwardEvent

         _children                  : []
         addChild                   : function(component as Object) as Object: m._children.push(component): end function
      }
   end function

   function _component_handleOrForwardEvent(event as Object) as Boolean
      handled = m.handleEvent(event)

      ' We did not handle the event, maybe our children will?
      if not handled
         for i = 0 to m._children.count() - 1
            handled = m._children[i].handleOrForwardEvent(event)
            if handled then exit for
         end for
      end if

      return handled
   end function

   function _component_handleEvent(event as Object) as Boolean
      return false ' No handling of events at this level
   end function

   ' -----------------------------------------------
   ' Class: Button

   function buttonCreate() as Object
      this = componentCreate()

      ' Override function handleEvent
      this.handleEvent   = _button_handleEvent
      this.performClick = _button_performClick
      return this
   end function

   function _button_handleEvent(event as Object) as Boolean
      buttonCodes = bslUniversalControlCodes()
      if event.getInt() = buttonCodes.button_select_pressed
         m.performOnClick()
         return true ' We handled this event
      end if

      return false ' We didn't handle this event -- it should be passed to others who may wish to handle it
   end function

   function _button_performClick() as Void
      ?"Button was clicked!"
   end function

   ' -----------------------------------------------------------------------------
   ' Run Loop

   function runloopCreate() as Object
      return {
         _exited : false
         _root    : componentCreate()
         run       : _runloop_run

         getRoot: function() as Object: return m._root: end function
      }
   end function

   function _runloop_run() as Void
      while not m._exited
         event = m._messagePort.getMessage()
         if event <> invalid then m._root.handleOrForwardEvent(event)

         ' ... snip other run-loop stuff like drawing ...
      end while
   end function
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Wed Apr 08, 2015 10:48 am

TYVM ... for your time and code!

I need to go over your framework 42 more times, but I'm starting to see similarity in what I've done.
( Is it common to create a framework and then become fuzzy on how it works? :oops: )

But that's part of the reason for the thread. I have a working menu that is non-modal, but it isn't quite the same as a roMessageDialog in look-n-feel. Thus the attempt to initially use and now attempt to roll my own. I am reconsidering this and wondering if it wouldn't be easier to try to spiffy up what I already have working, but due to some "genius" reasoning on my part, my_menu and my_textbox are tightly integrated. Saved time / code before, more discomfort today. :P

peace & 42
 
Rek
Posts: 97
Joined: Mon Jul 08, 2013 9:22 am

Re: fake Modal Menu with getMessagePort()

Wed Apr 08, 2015 1:21 pm

dev42 wrote:
Is it common to create a framework and then become fuzzy on how it works? :oops:


In short, yes. That's why separation of concerns and good documentation is critical to good architecture. If you have undocumented assumptions or dependencies, chances are in 8 months you'll forget about them.

dev42 wrote:
Saved time / code before, more discomfort today. :P


Been there. Sounds like time for a refactor! :D
 
User avatar
Komag
Posts: 808
Joined: Fri Aug 22, 2014 3:42 am

Re: fake Modal Menu with getMessagePort()

Wed Apr 08, 2015 1:35 pm

I try to revisit work done a few weeks back, see if my documentation is clear to me, and if not, refigure what I've done (since it's not THAT old I can get "back into it" pretty quick), and improve my notes accordingly.
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Wed Apr 08, 2015 5:20 pm

Thanks guys. Appreciate the help.

The following are off thread topic, but relate to the issues I'm having. Maybe I need a state machine? Or at the very least, more "finite" and less "unknown" situations?!


Rek wrote:
Sounds like time for a refactor! :D

In a twisted way of looking at all this, I am! :wink: Just took a long way to get... here.

Komag wrote:
I try to revisit work done a few weeks back, see if my documentation is clear to me, and if not, refigure what I've done (since it's not THAT old I can get "back into it" pretty quick), and improve my notes accordingly.

Awesome advice. I have a ton of "to do" notes. Better documentation would be helpful. Interestingly, I have a comment at the very top of each doEvent() func something that gives the impression that I intended to have only one function process events at any given time, but I haven't done it that way!

Also, I've never been a fan of flow-charting, but I'm thinking I *REALLY* need to get over it and sketch out what's supposed to be happening in order to have a way to compare what I think my code is doing and how I've implemented it. The same for what I'm debating with using multiple event loops with getMessagePort().
______________________________________________
update:

  • Naming convention may be my NEMESIS! My current doEvent() functions *process* button presses, but in my attempt to make a new SuperMenu, I confused this with what would be called when a component was selected/executed... ~ onClick.
  • Built in roku components aren't modal. *facepalm* They can be, but don't have to be! I'd still need to send in whatever functions need to be called regularly to be called in the new event loop...
  • Here's a different way of saying what I was initially asking:
    an anonymous genius wrote:
    U want to know whether you should have a kind of hierarchy with the event loop where one loop takes precedence over another. Or should the main loop be mutating like a plugin for each game state. When the modal dialog comes up it changes the game state that changes the event handlers. Personally i would try to keep the event handlers for the input pluggable, like your state machine idea. To me, i think of the input hardware as constant, so that should be one thing. And then when the game changes, the behavior triggered by the input naturally changes. So that would be your state transition in your state machine. But you may want to do the opposite. ... Maybe the roku system favors the hierarchical looping. Sometimes may want to avoid fighting the framework too much.
 
Rek
Posts: 97
Joined: Mon Jul 08, 2013 9:22 am

Re: fake Modal Menu with getMessagePort()

Thu Apr 09, 2015 11:28 am

Sounds like maybe you want a stack of components instead of a hierarchy. I was thinking more about a generic UI system like android's where different components on the screen can react to events (i.e. buttons, text boxes, etc.). But if you're trying to achieve something more like a pause screen in a game, it might make more sense to design your system as a stack of "GameStates".

With that approach, you would only pass events and things like physics ticks to the top-most "active" GameState. So, initially you have a single GameState in the stack (main menu), then the user presses "Start Single Player". At this point, you would create a new "SinglePlayerGameState" and push it onto the stack; making it the new "active" GameState. The MainMenuGameState would still be in the stack, but essentially idle (you may want to release resources used by idle states -- depends on your needs). Finally, if the SinglePlayerGameState receives an event that it interprets as a "pause" command, it will create a PauseGameState and push that onto the stack, making the SinglePlayerGameState idle as well. All you have to do then is pop states off the stack to go "back".

I hope all that makes some kind of sense...
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Thu Apr 16, 2015 3:10 am

Rek wrote:
Sounds like maybe you want a stack of components instead of a hierarchy.

stacks FTW. Well, at least in theory. I haven't gotten that far. In "refactoring" / "making new code" mode.

Here's what I think I understand ( yes, I re-read that 3x to make sure I had it right ), Menu's and sub-menu's will be on one Stack, but their components ( buttons etc ) will be Lists ( one per Menu ).

Since I haven't yet gotten to the "Stack" phase of all this, I'm not sure how it'll work on screen. It might be a simple situation where I treat the "SuperMenu of Awesomeness" Stack as both a Stack and a List. The reason for both would be to make sure everything is drawn that needs to be -> "for each" -> [ List ] and to send user input to the active sub-menu -> .GetTail() -> [ Stack ] ... [ ifList also has .RemoveTail() ]

As for where I'm at right now, I'm still trying to find more descriptive names for things *and* where to put functionality. For example ( WARNING: this is not for the faint of heart. Sleep deprivation played a factor in this. Continue reading at your own risk ): I considered making onClick() -> onClickAndExit() that would return a Boolean if the component closed the current sub-menu. Thankfully, I came to a better / clearer solution which was to simply have a Boolean flag "exitOnClick" in the component and check that instead. It added a line of code in the event loop dag-nab it! But it is much clearer. [ of course, now that I've typed all this out, I start to re-consider and think "exitAfterClick" or "closeDialogAfterClick" would be better names! ]

I also have some Q's about "global" vars or accessing variables of different objects from within a menu, but I'll save them for later.

The further I go down this rabbit hole, the more I wish I'd just use the built in SDK UI elements and bend them to my will. :wink:

peace, good night now & 42
 
dev42
Topic Author
Posts: 82
Joined: Thu May 24, 2012 9:43 pm

Re: fake Modal Menu with getMessagePort()

Mon Apr 20, 2015 12:11 pm

I've got a few more Q's in regard to adding / removing objects from the "allObjsToDrawStackList":
  • Would it be OK to make allObjsToDrawStackList a global?
  • or better to pass it into *all* offspring obj methods?
  • and what about the parent object... like appending a sub-menu to the parent menu?
History is repeating itself... or I was a better programmer before... whatever, I'm going to create a circular reference and link to the other thread.

Please follow the rabbit ... OOP: access parent obj & Inheritance

Who is online

Users browsing this forum: No registered users and 8 guests