{"id":13418082,"url":"https://github.com/jeremyong/Selene","last_synced_at":"2025-03-15T02:32:40.733Z","repository":{"id":13100922,"uuid":"15782383","full_name":"jeremyong/Selene","owner":"jeremyong","description":"Simple C++11 friendly header-only bindings to Lua","archived":false,"fork":false,"pushed_at":"2019-04-27T00:21:47.000Z","size":334,"stargazers_count":810,"open_issues_count":57,"forks_count":116,"subscribers_count":82,"default_branch":"master","last_synced_at":"2024-07-31T22:40:56.679Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeremyong.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-09T23:06:00.000Z","updated_at":"2024-07-07T09:34:16.000Z","dependencies_parsed_at":"2022-08-23T14:11:10.003Z","dependency_job_id":null,"html_url":"https://github.com/jeremyong/Selene","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyong%2FSelene","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyong%2FSelene/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyong%2FSelene/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeremyong%2FSelene/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeremyong","download_url":"https://codeload.github.com/jeremyong/Selene/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221532198,"owners_count":16838915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T22:00:58.329Z","updated_at":"2025-03-15T02:32:40.706Z","avatar_url":"https://github.com/jeremyong.png","language":"C++","funding_links":[],"categories":["TODO scan for Android support in followings","Scripting","C++","Language Bindings"],"sub_categories":[],"readme":"# Selene\n\n*SEEKING NEW MAINTAINER*\n\nSelene would love to have a new home :) The project makes it very simple to interface from C++ to Lua but needs\nsome love to manage pull requests, issues, Lua compatibility, and other improvements. I intend on creating a\nseparate organization for Selene that I can continue to sit in and weigh in feedback as I have time, but will allow\nfor multiple contributors. Please let me know if you're interested by emailing jeremycong@gmail.com. Of course,\nprevious and current active maintainers will go to the front of the line, but everyone will be considered!\n\nBest,\nJeremy\n\n[![Build Status](https://travis-ci.org/jeremyong/Selene.svg?branch=master)](https://travis-ci.org/jeremyong/Selene)\n\nSimple C++11 friendly header-only bindings to Lua 5.1+.\n\n## Requirements\n\n- Cmake 2.8+\n- Lua 5.1+\n- C++11 compliant compiler\n\n## Usage\n\nSelene is a headers-only library so you just need to include\n\"selene.h\" to use this project.\n\nTo build the tests, do the following:\n\n```\nmkdir build\ncd build\ncmake ..\nmake\n```\n\nThis will build a `test_runner` executable that you can run. If you wish to\ninclude Lua from another location, you made pass the `LUA_INCLUDE_DIR` option\nto cmake (i.e. `cmake .. -DLUA_INCLUDE_DIR=/path/to/lua/include/dir`).\n\n## Usage\n\n### Establishing Lua Context\n\n```c++\nusing namespace sel;\nState state; // creates a Lua context\nState state{true}; // creates a Lua context and loads standard Lua libraries\n```\n\nWhen a `sel::State` object goes out of scope, the Lua context is\nautomatically destroyed in addition to all objects associated with it\n(including C++ objects).\n\n### Accessing elements\n\n```lua\n-- test.lua\nfoo = 4\nbar = {}\nbar[3] = \"hi\"\nbar[\"key\"] = \"there\"\n```\n\n```c++\nsel::State state;\nstate.Load(\"/path/to/test.lua\");\nassert(state[\"foo\"] == 4);\nassert(state[\"bar\"][3] == \"hi\");\nassert(state[\"bar\"][\"key\"] == \"there\");\n```\n\nWhen the `[]` operator is invoked on a `sel::State` object, a\n`sel::Selector` object is returned. The `Selector` is type castable to\nall the basic types that Lua can return.\n\nIf you access the same element frequently, it is recommended that you\ncache the selector for fast access later like so:\n\n```c++\nauto bar3 = state[\"bar\"][3]; // bar3 has type sel::Selector\nbar3 = 4;\nbar3 = 6;\nstd::cout \u003c\u003c int(bar3) \u003c\u003c std::endl;\n```\n\n### Calling Lua functions from C++\n\n```lua\n-- test.lua\n\nfunction foo()\nend\n\nfunction add(a, b)\n  return a + b\nend\n\nfunction sum_and_difference(a, b)\n  return (a+b), (a-b);\nend\n\nfunction bar()\n  return 4, true, \"hi\"\nend\n\nmytable = {}\nfunction mytable.foo()\n    return 4\nend\n```\n\n```c++\nsel::State state;\nstate.Load(\"/path/to/test.lua\");\n\n// Call function with no arguments or returns\nstate[\"foo\"]();\n\n// Call function with two arguments that returns an int\n// The type parameter can be one of int, lua_Number, std::string,\n// bool, or unsigned int\nint result = state[\"add\"](5, 2);\nassert(result == 7);\n\n\n// Call function that returns multiple values\nint sum, difference;\nsel::tie(sum, difference) = state[\"sum_and_difference\"](3, 1);\nassert(sum == 4 \u0026\u0026 difference == 2);\n\n// Call function in table\nresult = state[\"mytable\"][\"foo\"]();\nassert(result == 4);\n```\n\nNote that multi-value returns must have `sel::tie`\non the LHS and not `std::tie`. This will create a `sel::Tuple` as\nopposed to an `std::tuple` which has the `operator=` implemented for\nthe selector type.\n\n### Calling Free-standing C++ functions from Lua\n\n```c++\nint my_multiply(int a, int b) {\n    return (a*b);\n}\n\nsel::State state;\n\n// Register the function to the Lua global \"c_multiply\"\nstate[\"c_multiply\"] = \u0026my_multiply;\n\n// Now we can call it (we can also call it from within lua)\nint result = state[\"c_multiply\"](5, 2);\nassert(result == 10);\n```\n\nYou can also register functor objects, lambdas, and any fully\nqualified `std::function`. See `test/interop_tests.h` for details.\n\n#### Accepting Lua functions as Arguments\n\nTo retrieve a Lua function as a callable object in C++, you can use\nthe `sel::function` type like so:\n\n```lua\n-- test.lua\n\nfunction add(a, b)\n    return a+b\nend\n\nfunction pass_add(x, y)\n    take_fun_arg(add, x, y)\nend\n```\n\n```c++\nint take_fun_arg(sel::function\u003cint(int, int)\u003e fun, int a, int b) {\n    return fun(a, b);\n}\n\nsel::State state;\nstate[\"take_fun_arg\"] = \u0026take_fun_arg;\nstate.Load(\"test.lua\");\nassert(state[\"pass_add\"](3, 5) == 8)\n```\n\nThe `sel::function` type is pretty much identical to the\n`std::function` type excepts it holds a `shared_ptr` to a Lua\nreference. Once all instances of a particular `sel::function` go out\nof scope, the Lua reference will automatically become unbound. Simply\ncopying and retaining an instance of a `sel::function` will allow it\nto be callable later. You can also return a `sel::function` which will\nthen be callable in C++ or Lua.\n\n### Running arbitrary code\n\n```c++\nsel::State state;\nstate(\"x = 5\");\n```\n\nAfter running this snippet, `x` will have value 5 in the Lua runtime.\nSnippets run in this way cannot return anything to the caller at this time.\n\n### Registering Classes\n\n```c++\nstruct Bar {\n    int x;\n    Bar(int x_) : x(x_) {}\n    int AddThis(int y) { return x + y; }\n};\n\nsel::State state;\nstate[\"Bar\"].SetClass\u003cBar, int\u003e(\"add_this\", \u0026Bar::AddThis);\n```\n\n```lua\nbar = Bar.new(5)\n-- bar now refers to a new instance of Bar with its member x set to 5\n\nx = bar:add_this(2)\n-- x is now 7\n\nbar = nil\n--[[ the bar object will be destroyed the next time a garbage\n     collection is run ]]--\n```\n\nThe signature of the `SetClass` template method looks like the\nfollowing:\n\n```c++\ntemplate \u003ctypename T, typename... CtorArgs, typename... Funs\u003e\nvoid Selector::SetClass(Funs... funs);\n```\n\nThe template parameters supplied explicitly are first `T`, the class\nyou wish to register followed by `CtorArgs...`, the types that are\naccepted by the class's constructor. In addition to primitive types,\nyou may also pass pointers or references to other types that have been\nor will be registered. Note that constructor overloading\nis not supported at this time. The arguments to the `SetClass`\nfunction are a list of member functions you wish to register (callable\nfrom Lua). The format is [function name, function pointer, ...].\n\nAfter a class is registered, C++ functions and methods can return\npointers or references to Lua, and the class metatable will be\nassigned correctly.\n\n#### Registering Class Member Variables\n\nFor convenience, if you pass a pointer to a member instead of a member\nfunction, Selene will automatically generate a setter and getter for\nthe member. The getter name is just the name of the member variable\nyou supply and the setter has \"set_\" prepended to that name.\n\n```c++\n// Define Bar as above\nsel::State state;\nstate[\"Bar\"].SetClass\u003cBar, int\u003e(\"x\", \u0026Bar::x);\n```\n\n```lua\n-- now we can do the following:\nbar = Bar.new(4)\n\nprint(bar:x()) -- will print '4'\n\nbar:set_x(-4)\nprint(bar:x()) -- will print '-4'\n```\n\nMember variables registered in this way which are declared `const`\nwill not have a setter generated for them.\n\n### Registering Object Instances\n\nYou can also register an explicit object which was instantiated from\nC++. However, this object cannot be inherited from and you are in\ncharge of the object's lifetime.\n\n```c++\nstruct Foo {\n    int x;\n    Foo(int x_) : x(x_) {}\n\n    int DoubleAdd(int y) { return 2 * (x + y); }\n    void SetX(int x_) { x = x_; }\n};\n\nsel::State state;\n\n// Instantiate a foo object with x initially set to 2\nFoo foo(2);\n\n// Binds the C++ instance foo to a table also called foo in Lua along\n// with the DoubleAdd method and variable x. Binding a member variable\n// will create a getter and setter as illustrated below.\n// The user is not required to bind all members\nstate[\"foo\"].SetObj(foo,\n                    \"double_add\", \u0026Foo::DoubleAdd,\n                    \"x\", \u0026Foo::x);\n\nassert(state[\"foo\"][\"x\"]() == 2);\n\nstate[\"foo\"][\"set_x\"](4);\nassert(foo.x == 4);\n\nint result = state[\"foo\"][\"double_add\"](3);\nassert(result == 14);\n```\n\nIn the above example, the functions `foo.double_add` and `foo.set_x`\nwill also be accessible from within Lua after registration occurs. As\nwith class member variables, object instance variables which are\n`const` will not have a setter generated for them.\n\n## Writeups\n\nYou can read more about this project in the three blogposts that describes it:\n\n- [first part](http://www.jeremyong.com/blog/2014/01/10/interfacing-lua-with-templates-in-c-plus-plus-11/).\n- [second part](http://www.jeremyong.com/blog/2014/01/14/interfacing-lua-with-templates-in-c-plus-plus-11-continued)\n- [third part](http://www.jeremyong.com/blog/2014/01/21/interfacing-lua-with-templates-in-c-plus-plus-11-conclusion)\n- [ref-qualifier usage](http://www.jeremyong.com/blog/2014/02/15/using-ref-qualifiers/)\n\nThere have been syntax changes in library usage but the underlying\nconcepts of variadic template use and generics is the same.\n\n## Roadmap\n\nThe following features are planned, although nothing is guaranteed:\n\n- Smarter Lua module loading\n- Hooks for module reloading\n- VS support\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremyong%2FSelene","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeremyong%2FSelene","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeremyong%2FSelene/lists"}