{"action":"closed","issue":{"url":"https://api.github.com/repos/31/RelEnt-engine/issues/2","repository_url":"https://api.github.com/repos/31/RelEnt-engine","labels_url":"https://api.github.com/repos/31/RelEnt-engine/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/31/RelEnt-engine/issues/2/comments","events_url":"https://api.github.com/repos/31/RelEnt-engine/issues/2/events","html_url":"https://github.com/31/RelEnt-engine/issues/2","id":137099929,"number":2,"title":"A \"paging\" model for persistence and loading.","user":{"login":"31","id":331300,"avatar_url":"https://avatars.githubusercontent.com/u/331300?v=3","gravatar_id":"","url":"https://api.github.com/users/31","html_url":"https://github.com/31","followers_url":"https://api.github.com/users/31/followers","following_url":"https://api.github.com/users/31/following{/other_user}","gists_url":"https://api.github.com/users/31/gists{/gist_id}","starred_url":"https://api.github.com/users/31/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/31/subscriptions","organizations_url":"https://api.github.com/users/31/orgs","repos_url":"https://api.github.com/users/31/repos","events_url":"https://api.github.com/users/31/events{/privacy}","received_events_url":"https://api.github.com/users/31/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/31/RelEnt-engine/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-02-28T21:50:35Z","updated_at":"2016-08-07T20:12:22Z","closed_at":"2016-08-07T20:12:22Z","body":"In a database module there needs to be some sort of way to load/unload partial sets of the database. It would be best if this were based on ES principles.\r\n\r\nIdeas:\r\n\r\n### `CPaged` component\r\n\r\nSome sort of `CPaged` component\r\n\r\nA system could detect (or manipulate itself) a `CPaged` component that indicates that other components on the entity and their relationships aren't present. The system could load them on demand and remove the `CPaged` component.\r\n\r\nThis seems very general, but has the (major) downside of having to check everything for `CPaged` before using it, because there's no way to know which entities could get `CPaged` at some point.\r\n\r\nI didn't write a lot for this because I think it's not a good way to go.\r\n\r\n### `Paged` relationship\r\n\r\nA new relationship, `Paged`\r\n\r\nLike `Indexed<T>` extends `Field<T>`, there could be a `Paged` that extends the functionality of `Indexed<euid>`. It indicates that that relationship may be a \"cut\" in the graph, so needs to be checked.\r\n\r\n(`Paged` should probably contain an `Indexed<euid>` rather than *being* one so that if something is changed from `Indexed` to `Paged` any non-checking usages are shown as compile-time errors. The reflection to find fields currently assumes they must be top-level, though, so this may be something to do later.)\r\n\r\nWhen loading from the file system, relationships are followed to determine what to bring into memory. All `Paged`s are not loaded. When one is required, the API of `Paged` gives a few ways to wait for the graph under it to be loaded:\r\n\r\n* Synchronous: on the same thread, the subgraph is loaded. Simplest.\r\n* Suspension of the entire world: the entire world--updates, querying, etc.--are all suspended until the load is complete. A callback provided to the system is then called before the world is resumed. Perhaps useful if you have outside-ES graphical updates.\r\n* Polling: it returns a bool indicating if the subgraph is loaded. (Note: if the reference is null, it will be loaded already but contain nothing!) Could also return some loading stats, like what stage of loading it's in, how many components loaded out of how many, etc.\r\n* Asynchronous: control returns to the system (through a callback, async/await, etc.) after the loading is complete. Useful in a situation where polling wouldn't normally be done so would be wasteful.\r\n\r\nIts unclear exactly when things should be paged out. It seems that the game code has a hand in this, because only it knows when a subgraph is going to be needed soon or is no longer necessary. A somewhat automatic method for some situations may be to only allow 1 subgraph of a particular `Paged` exist in memory--this would most likely work for level info, such as tile data. Most-recently-used with a cap may also be useful, but the cap seems like it would have to be very carefully set or else you'd get thrashing.\r\n\r\n**Con**: It might be hard to make sure a cut is good as a user of `Paged`. For example, an overworld contains many sublevels, and let's say the player contains all sublevels they have visited. Wanting to allow the levels to page out, the dev changes the sublevels' `Indexed<euid>` to `Paged`. Non-visited levels are successfully paged out, but visited ones are still loaded because they are referred to by the player. The most likely solution is making a \"level name\" component which pages \"level data\" that both the player and the overworld refer to, but in more complex example the solution may not be apparent."}}
{"actor":{"display_login":"31"}}