{"id":21885762,"url":"https://github.com/ohlidalp/refcountingobject-angelscript","last_synced_at":"2025-04-15T07:42:41.709Z","repository":{"id":65032687,"uuid":"531231296","full_name":"ohlidalp/RefCountingObject-AngelScript","owner":"ohlidalp","description":"Pass objects fuently between C++ and AngelScript, not worrying about the manual ref counting.","archived":false,"fork":false,"pushed_at":"2024-07-01T20:02:07.000Z","size":100,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T17:57:31.086Z","etag":null,"topics":["angelscript","c-plus-plus","interoperability"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ohlidalp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-08-31T19:33:49.000Z","updated_at":"2025-03-23T04:41:51.000Z","dependencies_parsed_at":"2022-12-28T20:28:24.249Z","dependency_job_id":null,"html_url":"https://github.com/ohlidalp/RefCountingObject-AngelScript","commit_stats":null,"previous_names":["ohlidalp/refcountingobject-angelscript"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohlidalp%2FRefCountingObject-AngelScript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohlidalp%2FRefCountingObject-AngelScript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohlidalp%2FRefCountingObject-AngelScript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohlidalp%2FRefCountingObject-AngelScript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ohlidalp","download_url":"https://codeload.github.com/ohlidalp/RefCountingObject-AngelScript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249030862,"owners_count":21201349,"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":["angelscript","c-plus-plus","interoperability"],"created_at":"2024-11-28T10:29:15.770Z","updated_at":"2025-04-15T07:42:41.665Z","avatar_url":"https://github.com/ohlidalp.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n# RefCountingObject system for AngelScript\r\n\r\n_Created 2022 by Petr Ohlídal_\r\n\r\n_https://github.com/only-a-ptr/RefCountingObject-AngelScript_\r\n\r\nThis mini-framework lets you use a single reference counting mechanism for both\r\nAngelScript's built-in garbage collection and C++ smart pointers. This allows you to fluently\r\npass objects between C++ and script context(s) without caring who created the object and where may\r\nreferences be held.\r\n\r\n## Motivation\r\n\r\nI maintain [a game project](https://github.com/RigsOfRods/rigs-of-rods)\r\nwhere AngelScript is an optional dependency\r\nbut at the same time plays an important gameplay role.\r\nI wanted to expand the scripting interface by exposing\r\nthe internal objects and functions as directly as possible, but I didn't want to do\r\nAngelScript refcounting manually on the C++ side.\r\nI wanted a classic C++ smart pointer (like `std::shared_ptr\u003c\u003e`) that would do it for me,\r\nand which would remain fully functional for C++ even if built without AngelScript.\r\n\r\n## How to use\r\n\r\nThe project was developed against AngelScript 2.35.1; but any reasonably recent version should do.\r\n\r\nTo install, just copy the 'RefCountingObject\\*' files to your project.\r\n\r\nDefine your C++ classes by implementing `RefCountingObject`\r\nand calling `RegisterRefCountingObject()` for each type.\r\n**Important:** Register the factory function as `\"@+\"` (auto handle)\r\nto satisfy the script ref counting expectation, see \"How it works\" below.\r\n\r\n```cpp\r\nclass Foo: RefCountingObject\u003cFoo\u003e{}\r\nFoo::RegisterRefCountingObject(engine, \"Foo\");\r\n\r\nstatic Foo* FooFactory() { return new Foo(); }\r\nengine-\u003eRegisterObjectBehaviour(\"Foo\", asBEHAVE_FACTORY, \"Foo@+ f()\", asFUNCTION(FooFactory), asCALL_CDECL);\r\n```\r\n\r\nDefine your C++ smart pointers by qualifying `RefCountingObjectPtr\u003c\u003e`\r\nand register each with `RegisterRefCountingObjectPtr()`.\r\nand use them in your interfaces. \r\nThese will become usable interchangeably from both C++ and script.\r\n\r\n```cpp\r\ntypedef RefCountingObjectPtr\u003cFoo\u003e FooPtr;\r\nFooPtr::RegisterRefCountingObjectPtr(engine, \"FooPtr\", \"Foo\");\r\n```\r\n\r\nFinally, use the smart pointers in your application interface.\r\n\r\n```cpp\r\nstatic FooPtr gf;\r\n\r\nvoid SetFoo(FooPtr f) { gf = f; }\r\nengine-\u003eRegisterGlobalFunction(\"void SetFoo(FooPtr@)\", asFUNCTION(SetFoo), asCALL_CDECL);\r\n\r\nFooPtr GetFoo() { return gf; }\r\nengine-\u003eRegisterGlobalFunction(\"FooPtr@ GetFoo()\", asFUNCTION(GetFoo), asCALL_CDECL);\r\n```\r\n\r\nIn C++, use just the smart pointers and you'll be safe.\r\n\r\n```cpp\r\nFooPtr f1 = new Foo(); // refcount 1\r\nSetFoo(f1);            // refcount 2\r\nFooPtr f2 = GetFoo();  // refcount 3\r\nf2 = nullptr;          // refcount 2\r\nf1 = nullptr;          // refcount 1\r\nSetFoo(nullptr);       // refcount 0 -\u003e deleted.\r\n```\r\n\r\nIn AngelScript, use the native handles.\r\n\r\n```\r\nFoo@ f1 = Foo();       // refcount 1\r\nSetFoo(f1);            // refcount 2\r\nFoo@ f2 = GetFoo();    // refcount 3\r\n@f2 = null;            // refcount 2\r\n@f1 = null;            // refcount 1\r\nSetFoo(null);          // refcount 0 -\u003e deleted.\r\n```\r\n\r\n## How it works\r\n\r\nAngelScript automatically increases refcount when passing pointers to application\r\nand expects the application to increase refcount when passing pointers to AngelScript.\r\nSee http://www.angelcode.com/angelscript/sdk/docs/manual/doc_obj_handle.html#doc_obj_handle_3\r\n\r\nAcross AngelScript documentation, the object constructor always pre-assigns refcount to 1,\r\nbut that would complicate using a smart pointer in C++. Thus, `RefCountingObject` leaves\r\nthe initial refcount at 0 and leaves it to either `RefCountingObjectPtr` (when constructing in C++)\r\nor the user-defined factory function (when constructing in AngelScript) to increase it.\r\nThe factory function can either explicitly call `AddRef()`\r\nor use the \"auto handle\" syntax `@+` which takes care of it automatically,\r\nsee http://www.angelcode.com/angelscript/sdk/docs/manual/doc_obj_handle.html#doc_obj_handle_4\r\n  \r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohlidalp%2Frefcountingobject-angelscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fohlidalp%2Frefcountingobject-angelscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohlidalp%2Frefcountingobject-angelscript/lists"}