Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tables need supporting #24

Open
Ambeco opened this issue Aug 9, 2013 · 7 comments
Open

Tables need supporting #24

Ambeco opened this issue Aug 9, 2013 · 7 comments

Comments

@Ambeco
Copy link

Ambeco commented Aug 9, 2013

I wrote a little test program here http://coliru.stacked-crooked.com/view?id=6a21d5531a6e1849dcccb1e3b5a4b0d2-cc73e281b3b6abc9bf6cf4f153b944a6) just to figure out what sort of syntax should be suggested.

Since lua refers to the state of the lua engine, I thought it might be more consistent to replace lua.set_global(N,V) and lua.get_global(N) with lua.global().set(N,V), where lua.global() returns the "global scope", allowing it to have the same syntax as every other subscope, without treating the lua object itself like just another hashtable.

Here's some API I came up for my simple test:

lua::table lua::global() //gets the global scope

lua::table lua::variant::get_as_table() //throws lua::not_a_table or lua::incorrect type or something

lua::table lua::variant::assign_new_table() //functions as "v = {}"
lua::variant lua::table::get(string) //not sure if this should throw if null or what
lua::variant lua::table::set(string, T) //obvious isn't it?

Functions passing values in/out of lua should be any lua types like lua::variant, or types for which lua::table assign_to_lua(lua::state& lua, const T& src, lua::variant& dst) or T create_from_lua(lua::state& lua, lua::variant& src) exist for cpp->lua and lua->cpp respectively.

As mentioned, these are all just to get the ball rolling on conversation, any and all of this should be hotly debated before anyone codes anything.

@Ambeco
Copy link
Author

Ambeco commented Aug 9, 2013

it occurs to me, template<class T> T lua::table::get_as<T>(string); would be incredibly handy as well. T can be lua::variant, lua::table, or any type for which T create_from_lua(lua::state& lua, lua::variant& src) exists.

@bananu7
Copy link
Member

bananu7 commented Aug 9, 2013

I agree, this is a priority now. Stay tuned for updates.

@Ambeco
Copy link
Author

Ambeco commented Aug 11, 2013

Part of the design behind having a seperate get and set functions was due to the theory that it would be difficult to have a lua::variant that refers to a variable who's value is null. It occurs to me that, in this light, the use of lua::variant::assign_new_table() is absurd. The "consistent" thing to do would be set(string, lua::new_table), which means you'd need a lua:new_table_type, with an instance of lua::new_table (similar to how nullptr works). This also reveals that requiring the first line of assign_to_lua to be lua::variant::assign_new_table() is absurd, and the correct API would be to have assign_new_table have the precondition that the target lua variable is a blank table. This also leads to simpler user code.

@Ambeco
Copy link
Author

Ambeco commented Aug 11, 2013

As another interesting thought, code like below might be handy, but would require a different design for tables

lua.set("alias_thing", { 
        {"name", "Cpp Aliases"},
        {"aliases", { 
            {"Duck", "MooingDuck"}, 
            {"Robot", "R.Martinho Fernandez"}, 
            {"Puppy", "DeadMG"} 
        },
        {"size", 3}
    });

This would require an overload lua::table::set(std::initializer_list<lua::table_element>), where table_element is something like

struct table_element {
    table_element(std::string, std::initializer_list<lua::table_element>) //or whatever string type the key is
    table_element(std::string, lua::table) //or whatever string type the key is
    table_element(std::string, lua::string)
    table_element(std::string, lua::int) //and etc
};

This design is unfortunately awkward, but you can't use std::pair because we don't know the second type, and I don't think you can use lua::variant unless it knows the actual name of the variable it refers to, and even if you tried, lua::variant would have to be constructable with the above constructors, which I assume would conflict with existing invariants. The table_element should be only used for the initializer lists of tables, and not used by user code.

This seems slightly hackish, so.... please think, critique, and discuss before implementing.

@bananu7
Copy link
Member

bananu7 commented Aug 11, 2013

That's why we have no table support yet. It's a complicated thing and hard to do right. I'll try to implement some for of prototype.

@Ambeco
Copy link
Author

Ambeco commented Aug 11, 2013

It occurs to me that my suggestion thus far can't iterate over members of a table, that might be another use for table_element, or maybe not. The lua syntax is for key,value in pairs(table) do ... end, or for key, value in ipairs(table). Not sure what a good syntax for C++ would be, should lua::table have a lua::table_iterator<table_element> begin() and corresponding end() iterators for the first case? or maybe lua::table_iterator<std::pair<lua::variant, lua::variant>>?

@Ambeco
Copy link
Author

Ambeco commented Aug 14, 2013

Just realized T create_from_lua(lua::state& lua, lua::variant& src) doesn't work because one obviously cannot overload on the return type. However, a similar function would be required for returning C++ objects from lua::state::call. Since we don't want to force C++ types to be default constructable if we don't have to, create_from_lua should probably have a T* parameter, which would be confusing if not used, though the only use I could see is placement new the return type in that space, which seems like a terribly confusing idea.

@ghost ghost mentioned this issue Sep 24, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants