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

[Discussion] Dirty Flags and Invalidation of Cache System #44

Closed
BraedonWooding opened this issue Apr 11, 2017 · 8 comments
Closed

[Discussion] Dirty Flags and Invalidation of Cache System #44

BraedonWooding opened this issue Apr 11, 2017 · 8 comments

Comments

@BraedonWooding
Copy link
Member

Issue by BraedonWooding
Wednesday Mar 08, 2017 at 06:09 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT
Originally opened as TeamPorcupine/ProjectPorcupine#1788


Currently if you want to make something reliant on a setting but don't want to do a getSetting every second (aka cache the setting) then you have to edit that settings code to tell you to get the new setting (or do a timing system), this is just a simple example that hopefully illustrates the problem we have, this is a problem that is less relevant for settings (since well timing is at very least a semi-reasonable setting, and if you build the settings yourself you can implement them to trigger your stuff), BUT for a lot of other situations it isn't, this includes pathfinding, jobs...

So I thought what if we implemented a dirty flag system, it would essentially consist of a big enum (and most likely would actually not be an enum but be a similar system so modders could add items, or it would be a precomputer/compiled enum + postcomputed/runtime 'enums') then we could apply bitwise operators (& / |) to chain the enums this could allow users to just essentially do integer operations to check if their flag has been pressed (and we could even implement filters on our end and an array of actions or dictionary of filter to array of actions or whatever).

So I kind of want to gather some discussion on what people think about this? Most likely it would just be a call or xml/json/skon file to hookup to the flag system which would just be a single event (or us simulating that through an array of actions linked to dictionary or whatever) called something like 'InvalidateCache' (though as per with almost all our functions the name isn't important but that is a quite a good name especially for our side), and it would have a signature simply like void InvalidateCache(int cacheFlags). LUA has bitwise so it's not harder/easier to use C# (and actually would be easier with LUA since it has a little more support for runtime enums, since they are implemented as tables).

So wait how would you interface with this? Well I was thinking you would just tell the system that this flagged has changed (i.e. CacheFlags.SetFlag(Flags.SettingsChanged, true)), then the system would do an invalidation cache next frame (or maybe next second tick), but obviously you could also trigger an invalidation cache by maybe doing something like CacheFlags.TriggerInvalidationCache() (again these are just some placeholder names to get across meaning). Then it would go out and tell everything that has filtered to receive the values to update. Then after it'll flip back all the flags, most likely to avoid weird mismatches of updating flags, it will get the current flag values by & all the flags that are true, then it will turn them all to false, then it will do the call with that value calculated.

Anyways what do you guys think? This system could boost performance and cleanup code, it could also help things like pathfinding (maybe each room has an 'enum value' then when a change occurs in a room it dirties pathfinding for that room?).

@BraedonWooding
Copy link
Member Author

Comment by crazyfox55
Wednesday Mar 08, 2017 at 07:29 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT


Why not just have an event for each setting? Then people can just register to those events. Anytime a setting changes it calls the event.

@BraedonWooding
Copy link
Member Author

Comment by BraedonWooding
Wednesday Mar 08, 2017 at 07:32 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT


That has awful scalability and memory problems, especially since all settings are done as a mod and aren't hardcoded so it would have to do some runtime trickery.  But i can see what you are saying, also as I said the settings was one example, there are many other examples not related to settings that need this kind of system.  Having one action per setting is kind of like having one big action with a filter (which is what I suggested) but the filter is more scaleable without memory problems.

@BraedonWooding
Copy link
Member Author

Comment by crazyfox55
Wednesday Mar 08, 2017 at 07:46 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT


I must be confusing something on where the settings are. As a side note wouldn't enum flags limit you to 32 settings? Also why would you need to cache a setting, does getting a setting really take that much computation?

@BraedonWooding
Copy link
Member Author

Comment by BraedonWooding
Wednesday Mar 08, 2017 at 08:00 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT


To answer your questions consecutively:1) Settings are located as they have always been but they are set using a code based UI menu this is softcoded completely to allow full control over settings (with some presets and helper functions) this is more focused on other things other than settings.  Settings was a singular example out of many...2) yes for an int32 flat enum, but we would most likely use an 'enum' mixed with a bit array since that can hold a number much larger than 32 (i think its 'infinite' as in list infinite but dont quote me on that hehe).3) No it isn't but if you have to do it every frame to check if it has changed then that's useless computation and again its not just about settings, imagine having it for pathfinding. 
If a lookup takes a few ms, I think its around 0.03 then if u add function calls a try get value and a convert u get to around 0.1 tho again this is rough as hell.  Then if u run that every frame, for 30 settings yehhh it can seem to cause a slight slowdown.  But again thats mostly micro optimising it mostly comes down to lets make finding if a setting has changed less ugly, and other systems like performance hud and settings menu already use dirty functions for certain things to refresh them.  And other things like pathfinding implement similar structures... u could also have a saving flag / loading flag and so on.  Don't get too caught up in the one example its quite a bit larger than that :)

@BraedonWooding
Copy link
Member Author

Comment by crazyfox55
Wednesday Mar 08, 2017 at 08:12 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT


An enum mixed with bit array would hold plenty of information. 4 billion settings haha. I agree that it's needless computation and should be optimized out by better program flow.

With one big action that just sends a filter wouldn't that require a lot of checking on which bits are set?

@BraedonWooding
Copy link
Member Author

Comment by BraedonWooding
Wednesday Mar 08, 2017 at 08:14 GMT # Sample: Friday Sep 13, 2013 at 22:58 GMT


Bit checking is cheaper than division and multiplication so not a big concern just like saying '(resultOfAllFlags & myFlag) == myFlag'

@BraedonWooding
Copy link
Member Author

Want to just add that my last comment is even slightly incorrect for bit arrays you can just do an index to return if it's true or not, this is much much faster, around the speed of an array access.

@BraedonWooding
Copy link
Member Author

Closing, old issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant