Last active
January 15, 2026 04:54
-
-
Save andrewgotow/e66ec493e4aedfb8f47287f5203d7e2b to your computer and use it in GitHub Desktop.
Resource Linked List
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <vector> | |
| #include <algorithm> | |
| struct Resource; | |
| struct ListLink { | |
| Resource* ptr; | |
| unsigned idx; | |
| ListLink() | |
| : ptr(nullptr), idx(0) | |
| {} | |
| ListLink(Resource *ptr, unsigned idx) | |
| : ptr(ptr), idx(idx) | |
| {} | |
| }; | |
| struct Resource { | |
| std::vector<ListLink> links; | |
| unsigned refCount = 0; | |
| std::string name; | |
| Resource(const std::string& name) | |
| : name(name) | |
| {} | |
| ListLink AllocLink() { | |
| // Find the first unused link in our vector of links. | |
| for (unsigned idx = 0; idx < links.size(); ++idx) { | |
| if (links[idx].ptr == nullptr) | |
| return {this, idx}; | |
| } | |
| // All links are currently in use! Push and return a new one! | |
| links.emplace_back(); | |
| return {this, (unsigned)links.size()}; | |
| } | |
| void IncRef() { | |
| std::cout << "IncRef: " << name << "\n"; | |
| ++refCount; | |
| } | |
| void DecRef() { | |
| std::cout << "DecRef: " << name << "\n"; | |
| if (--refCount == 0) | |
| delete this; | |
| } | |
| }; | |
| struct CommandBuffer { | |
| ListLink refs; | |
| void RefResource(Resource& res) { | |
| res.IncRef(); | |
| // Allocate a "next" link within the resource. | |
| // This link will be used as a "next pointer" in the linked resource list. | |
| ListLink link = res.AllocLink(); | |
| // Now swap the current refs list with the allocated link. | |
| // This will push the link into the front of the list. | |
| res.links[link.idx] = refs; | |
| refs = link; | |
| } | |
| void ReleaseAll() { | |
| // Iterate over the list of links and decrement refs. | |
| ListLink link = refs; | |
| while (link.ptr) | |
| { | |
| Resource* res = link.ptr; | |
| link = res->links[link.idx]; | |
| res->links[link.idx].ptr = nullptr; | |
| res->DecRef(); | |
| } | |
| } | |
| }; | |
| int main() { | |
| Resource resA("A"); | |
| Resource resB("B"); | |
| CommandBuffer cmdA; | |
| CommandBuffer cmdB; | |
| cmdA.RefResource(resA); | |
| cmdB.RefResource(resA); | |
| cmdA.RefResource(resB); | |
| cmdB.ReleaseAll(); | |
| cmdA.ReleaseAll(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment