Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using the debugger with short-lived contexts #200

Closed
lut0pia opened this issue Jun 30, 2021 · 4 comments
Closed

Using the debugger with short-lived contexts #200

lut0pia opened this issue Jun 30, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@lut0pia
Copy link
Contributor

lut0pia commented Jun 30, 2021

Hello!

I am having some trouble integrating the debugger in my engine, and I have a few solutions but I'm unsure which one makes the most sense from the perspective of RmlUi's philosophy.

For starters, in my engine I can have one RmlUi context per camera, which means that at any given moment I could have no context at all, or multiple contexts at once. This does not seem to play well at all with the way the debugger works. The debugger can be initialized with a context, which will become its host context, and then it can either debug its own host context or any other context. However, as soon as the host context for the debugger is released, it seems impossible to make use of the debugger again, since Rml::Debugger::Initialise will fail because the plugin already exists, and Rml::Debugger::SetContext will only change the context to be debugged. In any case it ends up crashing when trying to use the debugger.

Here are the solutions I found (from more involved on my side to more involved on RmlUi's side):

  1. Create a completely separate context which is always live, specifically for the debugger. This seems pretty neat on the surface and it does play well with the singleton plugin architecture. However I'm unsure about how to treat input and rendering here. Do I feed input to both the debugger context and the debugged context? Wouldn't that mean that I could accidentally trigger things while clicking to select an element for instance? Maybe I could check if the debugger if visible and if so only feed input to the debugger context. And rendering seems strange because I would have to align the debugger context with the debugged context right? I have not tested this approach yet but if you tell me that this is the way it is intended to be then I'll give it a try. I'm mostly wary of this approach because it's not the way it's implemented in any of the samples as far as I know.
  2. Change the way I handle my contexts and cameras to have only a single context all the time, and use documents for each camera for instance (which would have to be aligned in some way in the context, via SetContentBox I suppose?). That seems fine to me if SetContentBox does what I think it does. Is it closer to the RmlUi phisolophy perhaps?
  3. Allow the debugger to change host context via a new method (or remove the first test from Rml::Debugger::Initialise). This is something I've tested locally and that seems to work. I added a method Rml::Debugger::SetHostContext that can reinitialise the debugger with a new host context (see here: lut0pia@25d359b). It works fine for my use case, I'm not entirely sure that I'm not missing something but I can definitely jump from context to context without crashing, and input and rendering work like a charm because the debugger coexists nicely with the rest of the documents. If this approach seems good to you, I can create a PR with the new method (or with the modified Rml::Debugger::Initialise).
  4. Allow one debugger per context. This one I have neither tested nor investigated much, but to me it seems interesting. I'm guessing this is the furthest from the current RmlUi plugin philosophy. I'm including this idea however for completeness.

I would love to have your input on all of this. Thanks again for this wonderful library :)

@mikke89
Copy link
Owner

mikke89 commented Jun 30, 2021

Hi, and thank you for the kind words!

The way I use the debugger is having a dedicated context for it, as you suggest. Inputs are first submitted to the debugger (this is always considered to be on top when active), then if they are not captured here they are submitted to the next context and so on. This is handled automatically the way I have structured this so it didn't take any effort to do it this way for me.

I don't fully understand how the contexts are layed out in your case and what you mean by aligning things. But generally to position and size windows, use RCSS properties just like for any other element. The document is really just an absolutely positioned element.

In any case, I can see how in your situation it might be simpler to change the host context, I'll gladly accept a PR if you submit one. I think we should intentionally make the name of the function a bit more complicated so users don't accidentally use it. Maybe something like RestartDebuggerInHostContext()? We should also properly shut it down first before we initialize it. Right now I think this implementation will leak if the host context is not shut down already. Maybe just Restart(), since this is essentially what it's doing then?

Let me know what you think. And also I'd love to see some screenshots when you feel ready to share some, I like to see people's creations, feel free to post them in the gallery :)

@lut0pia
Copy link
Contributor Author

lut0pia commented Jul 1, 2021

Thank you for your reply!

I see, having a dedicated debugger context does seem like the cleanest way to do things. That totally makes sense for input, thank you! Well my cameras can define the part of the screen they render to, currently that means that when queueing rendering commands from the RmlUI context, they will be drawn with a specific viewport for that camera (this can be useful for HUDs in split-screen for instance), and it also means I set the context's dimensions to be that of the pixels available to the camera on the screen. This is fine on its own but I have no idea how that would interact with another context for debugging, if the debugging context is just fullscreen while the debugged context is some specific part of the screen for instance, then probably the outlines it will try to draw will be misaligned right? If so then that means whenever I try to debug a context, I would have to replicate the same offset/dimensions of the debugged context with the debugger context, which shouldn't be difficult but seems pretty messy. Maybe I should just always use fullscreen contexts and deal with screen partitioning inside the context instead?

You're right I was assuming that the host context was shut down. Which makes me think maybe it would be even better to make that new method just Shutdown, since it would allow to do another Initialise afterwards, and is pretty explicit in what it does. And it could also make sense if someone wants to really shut down the debugger when the user no longer wants to use it (instead of just toggling visibility). Or I'm fine with going with Restart if you'd prefer. What do you think?

Believe me I would have submitted screenshots already except I am but a mere engine programmer and all my UI currently consists of colored rectangles with text which is definitely not gallery-worthy x) My graphic designer partner will be working on the UI at some point however and I know she will be able to do really neat things with it :)

@mikke89
Copy link
Owner

mikke89 commented Jul 1, 2021

Yeah, I guess this alignment is just one of those things one has to figure out. I think all your proposals sound reasonable so it's just a matter of picking one.

Yes, absolutely, Shutdown makes a lot of sense, I say we go with that!

Very cool, looking forward to see what your partner comes up with! :)

@lut0pia
Copy link
Contributor Author

lut0pia commented Jul 1, 2021

Thanks again for your help :)

@lut0pia lut0pia closed this as completed Jul 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants