BenChung / KRPC.jl

A kRPC client for Julia
MIT License
3 stars 4 forks source link

Received enums don't match the number defined in code #14

Open Rhahi opened 1 year ago

Rhahi commented 1 year ago

Enums seem to have a doubling issue.

Discovery

using KRPC
import KRPC.Interface.KRPC as KK
import KRPC.Interface.KRPC.RemoteTypes as KR
import KRPC.Interface.KRPC.Helpers as KH

# first, launch a vessel and then get connection.
conn = ... (KRPC.KRPCConnection)

# create a KRPC struct required by CurrentGameScene
mykrpc = KR.KRPC(conn)
KH.CurrentGameScene(mykrpc) == KK.EGameScene_Flight

The last expression evaluates false.

Experimentation

Just like the last issue, the code for EGameScene lies in generated.jl, so the fix should be in code generation.

struct EGameScene <: kRPCTypes.Enum
    value::Int32
end
const EGameScene_SpaceCenter = EGameScene(0)
const EGameScene_Flight = EGameScene(1)
const EGameScene_TrackingStation = EGameScene(2)
const EGameScene_EditorVAB = EGameScene(3)
const EGameScene_EditorSPH = EGameScene(4)
export EGameScene

Now, actual value I get is this:

Situation generated.jl Received number
space center 0 0
flight 1 2
tracking station 2 4
VAB 3 6
SPH 4 8

So there is some number doubling going on.

Suggestion

I am not sure if this doubling is coming from KSP/KRPC, or from KRPC.jl. A quickest fix would be to change the const enum values, so that generated.jl gets

const EGameScene_SpaceCenter = EGameScene(0)
const EGameScene_Flight = EGameScene(2)
const EGameScene_TrackingStation = EGameScene(4)
const EGameScene_EditorVAB = EGameScene(6)
const EGameScene_EditorSPH = EGameScene(8)

I think this can be done by changing codegen.jl by changing in line 286

 enum in service.enumerations
    enumName = Symbol("E" * enum.name)
    push!(enumerations_ast, :(struct $enumName <: kRPCTypes.Enum value::Int32 end))
    for val in enum.values
        push!(enumerations_ast, :(const $(Symbol("E" * enum.name * "_" * val.name)) = $enumName($(val.value*2))))
---> scroll                                                                                                ^^
    end
    push!(enumeration_names, enumName)
end

Do you think this is a reasonable way to do it? If so, I can later make a PR when I start working with enums, test with some other parts that use enums and see if they work not just for the game situation but for everything else, too. (parachute states come to mind)

Workaround

Just being aware of this phenomenon and put that into account during enum comparisons; for example, I can define a function

import Base: ==
function ==(a::KRPC.kRPCTypes.Enum, b::KRPC.kRPCTypes.Enum)
    return a.value == b.value*2
end

and then the comparions will work and be a bit more future-proof, as long as I stick to the convention that left is rpc, right is code.

Rhahi commented 1 year ago

An update on this issue. I noticed that the enum numbers were correct with parachute enums. (tested in Vanilla + KRPC + kOS)