Skip to content

State Management #88

@ahnlak

Description

@ahnlak

There are a number of 'global' states that affect all drawing primitives (pen(), blend() et al), but currently no way of determining their current state or restoring them.

While this isn't a problem in a simple, single program it gets complicated when (for example) you have a library routine that needs to use a specific, non-default blend mode without wanting to inflict global changes. There are a number of ways to approach this, which I think I've covered below, but I'd like some feedback on which is preferred.

1. Do Nothing

  • user code assumes that global modes are always set to their defaults on returning from library functions, and reset things as required
  • alternatively, library code examines internal API variables (_pen, _bf and friends) to maintain / restore state

Pros: nothing needs to be done to the API
Cons: lots of work for user code, and/or needing to look at API internals that should be private

2. Return Previous State

  • modify the API so that functions that change state return the previous state, instead of returning void
  • these return values can be safely ignored and the API functions as before
  • would need new structures (point & rect) for more complex returns

Pros: 'neutral' change, that allows libraries to manage their own state changes if they choose to.
Cons: can't be used for states with multiple variables (camera(), clip()) without new structures. Old school (or is that a pro?)

3. State Getter Functons

  • add read_pen(&color) style readers, to allow anyone to query the current individual states
  • return via reference arguments to allow for states with multiple variables

Pros: copes with multi-variable states like camera()
Cons: clunky. horrible. return values by reference feels dirty.

4. State Save / Restore

  • new global save_state() / restore_state() functions, to push the full state onto an internal stack
  • (optional) functionality-specific functions to allow just drawing or audio states to be saved / restored

Pros: makes it trivial to use
Cons: feels heavyweight and contrary to the existing spirit of the API. Potential memory leaks if caller doesn't restore the state or otherwise clear the stack.


My personal preference is for (2), because that fits in most neatly to how my brain works. The fact it won't work for clip() / camera() / cursor() without inventing new structures is a bit of a red flag, and although my instinct is that the main issues are more likely to be around pen() and blend(), I'm aware that I'm projecting what I need, rather than what makes sense for the API.

I'm not keen on a solution that only fixes half the problem, however.

I'll probably end up implementing one of these for my own sanity and while I'm happy to keep it as a secondary library, if we can think of a workable solution it would be nice to be able to be able to share with everyone.

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions