oakmound/oak

provide renderable type that renders the renderable returned by a function (updated every frame)

Closed this issue · 7 comments

Often I end up with a GetR() method on one of my types that returns its corresponding renderable. These end up being a pain to use because I have to undraw the old renderable, then draw the new one. It often ends up being easier to make a custom type that implements the renderable interface, even when everything the type deals with is already a renderable.Renderable.

200sc commented

Have you looked into using a render.Switch?

I guess there are two things here, are you trying to switch between a small set of potential images that are very different? Then consider the switch and loading it up front (makes game have less hitches!), we did that for example with facing left versus right or having cards up versus down.
If you want to say apply an effect to a renderable consider just modifying a modifyable. We do this when we need to change the colors on the fly for example.

Yes, and it would require refactoring my code completely. Also I made a working implementation, it's very simple.

render.Switch honestly doesn't seem very clear to me. It has a ton of methods, and most of the doc comments are less than helpful.
It also can't handle any logic, and you would still need to use render.CompoundM or Attach, neither of which have worked great for me in the past. Specifically Attach often makes things lag behind the thing they are attached to, which isn't a great effect.

I think this implies that there are a few things we should address here:

  1. render.Switch not being clear, maybe if you can pinpoint the parts that dont make sense and we can work together to update the docs.
  2. figure out why compoundM is needed and not compatible with render.Switch

I guess it's fairly clear what it does, but now really how. The biggest things for me is IsInteruptable() and IsStatic(). The documentation for these methods has a major case of func DoFoo() // does foo.

My question is this: is there a reason what I describe shouldn't exist? The implementation for it is very simple.

200sc commented

Switch, and other types that have underlying renderables, support utilities like IsInterruptable so that the specific functionality of the underlying renderable can still operate. There is extensive documentation on what exactly this call in particular means: https://github.com/oakmound/oak/blob/master/render/interruptable.go

// NonInterruptable types are not always interruptable.  If something is not
// NonInterruptable, it is equivalent to having IsInterruptable always return
// true.
//
// The intended use of the Interruptable datatypes is entirely external--
// oak does not use them internally. The use case is for an entity that has
// a set of potential animations, and attempts to switch from one animation
// to another. The Interuptable boolean should represent whether that
// animation should be able to be switched out of before it ends.
//
// Because this use case is minor, this is a candidate for removal from render
// and moving into an auxiliary package.
//
// Unless otherwie noted, all NonInterruptable types are interruptable when
// they are initialized and need to be switched (if the type supports it) to
// be non interruptbable.
type NonInterruptable interface {
	IsInterruptable() bool
}

IsStatic is intended to tell you whether a renderable is animating or not.

As far as whether this should exist in oak or not: the concern for me is "if it's so simple, why does it need to be in oak"? Which comes down to a philosophical decision-- what do we provide vs. what tools do we provide to allow users to write their own implementations? For the specific case of "a function that is a renderable" it sounds simple and elegant enough to be a good addition to me, but I do want to emphasize there is a current solution for this, and its to use string-keyed Switch types.