loopier / animatron

Animatron for Godot 4.x <
MIT License
16 stars 1 forks source link

Generic command handling #3

Closed loopier closed 8 months ago

loopier commented 1 year ago

@totalgee wrote:

Not sure I totally understand yet how your generic command handling works. If I want to add "set color" for Actors, I would add a new entry in nodeCommands, and then somehow it dispatches the correct thiing... But in this case I need to get some sub-objects (e.g. a ShaderMaterial) and then set some arbitary value on it. Nothing so far seems to be written in a "special case" like this, but how would you do it?

In the old days, it was:

func colorActor(inArgs, sender):
  var args = getActorsAndArgs(inArgs, "colorActor", 3, sender)
  if args:
    var rgb = Vector3(args.args[0], args.args[1], args.args[2])
    for node in args.actors:
      setShaderUniform(node, "uAddColor", rgb)

static func setShaderUniform(node, uName, uValue):
  var image = node.get_node(actorAnimNodePath)
  image.material.set_shader_param(uName, uValue)
loopier commented 1 year ago

I'd put it in the coreCommands with the mapped value probably being the callable to your colorActor method.

There are different command map dictionaries depending on how messages should be handled:

Does it make sense? I know its a bit confusing, but I think it makes it easier to implement new stuff. The hardest part may be knowing in what dictionary it must be added. Naming of the dictionaries might not be very helpful in this regard and should probably change? Can you think of a better way? All dictionaries are parsed in the same function, which I think is the most confusing of all. But passed this point, everything is very intuitive and I don't think we'll need too change much in this function (just if we need any other kind of dictionary).

In your case I'd probably add it to coreCommands:

var coreCommands: Dictionary = {
  // ...
  "/color": colorActor,
}

# the sender is handled by the parser before calling this method so we don't need to add it as argument
func colorActor(actor: String, red: float, green: float, blue: float) -> Status: 
    var result = getActor(actorName)
    if result.isError(): return result
    var node = result.value
    var rgb = Vector3(red, green, blue)
    setShaderUniform(node, "uAddColor", rgb)
    return result

func setShaderUniform(node, uname, uValue):
    # the code to change the color
loopier commented 1 year ago

I think arrayCommands is unnecessary. We could use a common callable for commands that need arguments to be passed as an array, like we do in nodeCommands with methods callActorMethodWithVector and the like. Maybe name it callMethodWithArray?

I'm not sure we can unify nodeCommands and coreCommands because the former passes the command address (the dictionary key) as first argument and that is parsed in parseCommand.

totalgee commented 1 year ago

In your case I'd probably add it to coreCommands:

Thanks, I did that in 326d475. The support for /color is now there, as it was with the Godot 3.x version, using a very simple shader for now. BTW, what happened to the docs directory we used to have, with the Markdown documentation? Where should I document this new OSC command?

loopier commented 1 year ago

what happened to the docs directory we used to have, with the Markdown documentation? Where should I document this new OSC command?

I created a new issue to discuss the help system.

loopier commented 8 months ago

This issue has been resolved at some point (not sure when, though...)