Native enum in ChaiScript


#1

Hi all,

Imagine I have a state of my player which I store in my global variable “PlayerState”. States could be: IDLE, IN_MENU, RUNNING_AROUND, DRIVING_VEHICLE, ENTERING_VEHICLE etc.

From what I see, currently there is no option to define something globally other than “global” itself.
So I would have to assign an integer to the global variable for each state that exists. It would be much easier if I could do:
enum PLAYER_STATE
{
IDLE,
IN_MENU,
RUNNING_AROUND,
DRIVING_VEHICLE,
ENTERING_VEHICLE
}

global PlayerState = IDLE;

def EnterVehicle()
{
PlayerState = ENTERING_VEHICLE;
}
def DoSomething()
{
switch (PlayerState) {
case IDLE: { },
case RUNNING_AROUND: { }
}
}

You should be able to assign numbers just like in C++.


Also this could be helpful:
enum PLAYER_STATE (+= 10)
{
THIS_IS_ZERO,
THIS_IS_TEN,
THIS_IS_TWENTY,
}


Furthermore, why is there no preprocessor for #define?

Thanks!


#2

Code something like this will get an enum into the script side.

The enum you want to add:

typedef enum PLAYER_STATE
{
    IDLE,
    IN_MENU,
    RUNNING_AROUND,
    ENTERING_VEHICLE,
} PLAYER_STATE;

A way to construct a module that will add the enum to the scripting:

class My_Lib
{
public:

    static chaiscript::ModulePtr library(chaiscript::ModulePtr m = std::make_shared<chaiscript::Module>())
    {
        using namespace chaiscript;
        using namespace bootstrap;

        utility::add_class<PLAYER_STATE>(*m, "PLAYER_STATE",
        {
            { PLAYER_STATE::IDLE, "IDLE" },
            { PLAYER_STATE::IN_MENU, "IN_MENU" },
            { PLAYER_STATE::RUNNING_AROUND, "RUNNING_AROUND" },
            { PLAYER_STATE::ENTERING_VEHICLE, "ENTERING_VEHICLE" },
        });
    }
};

Add the module “My_Lib::library()” to your engine, then from the script you can use PLAYER_STATE as a type.

Note that some of the typedef stuff on the enum may not be necessary (or good style), but in my case I am maintaining COM compatibility, and the construct shown plays well with exposing the enum through a COM interface definition.


#3

Hello ttemple,
thanks for your fast reply. But unfortunately this is what I am not able to do. I know you can expose it from C++.

My application runs scripts which are written by end-users. Meaning they have no access to C++ nor do I want them to do anything in C++.

So they are limited to what ChaiScript offers and what I handle them via C++.

Thanks.


#4

Hm, not getting your problem. I use what ttemple showed above, and it works.
With the bindings above you could use IDLE in script, which would be PLAYER_STATE::IDLE on the c++ side.
If you want to do something like that purely in script, just assign a bunch of globals, or a global struct.

global PLAYER_STATE_IDLE = 10;
global PLAYER_STATE_DEAD = 11;
global PLAYER_STATE_HAPPY = 12;
PLAYER_STATE_IDLE // 10
// or
class PLAYER_STATE_CLASS {
    def PLAYER_STATE_CLASS() {
        this.IDLE = 10;
        this.DEAD = 11;
        this.HAPPY = 12;
    }
}
global PLAYER_STATE = PLAYER_STATE_CLASS();
PLAYER_STATE.IDLE // 10

#5

Could expose it as an std::map?


#6

No really a convenient solution for an end-user who does not have access to C++.
You are asking to create a bunch of global variables instead of having a nice enum.