From 3d4ac1ba23a05907dc82d944e34354d528926f90 Mon Sep 17 00:00:00 2001 From: rambetter Date: Sun, 23 Jan 2011 09:12:34 +0000 Subject: [PATCH] Fixing filters. I didn't realize they were so broken. The fix is safe and should not break plugins or anything else. git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@437 8a3a26a2-13c4-0310-b231-cf6edde360e5 --- radiant/filters.cpp | 117 +++++++++++++++++++++++++++++++++--------- radiant/filters.h | 3 +- radiant/main.cpp | 2 +- radiant/mainframe.cpp | 9 +--- 4 files changed, 96 insertions(+), 35 deletions(-) diff --git a/radiant/filters.cpp b/radiant/filters.cpp index 17a91195..27ca8437 100644 --- a/radiant/filters.cpp +++ b/radiant/filters.cpp @@ -30,14 +30,38 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "stdafx.h" -// type 1 = texture filter (name) -// type 3 = entity filter (name) -// type 2 = QER_* shader flags -// type 4 = entity classes -// type 5 = surface flags (q2) -// type 6 = content flags (q2) -// type 7 = content flags - no match (q2) -bfilter_t *FilterAdd(bfilter_t *pFilter, int type, int bmask, const char *str, int exclude) +/* + Rambetter on Sun Jan 23, 2011: + + What follows is a discussion of the introduction to some new members and functions + such as baseFilters, baseFilterExcludes, FilterAddImpl(), and so on. + + There was a problem that "base" filters were not taking effect as a result of + user action such as clicking a filter checkbox. The reason why the base filters + were not being updated is because the previous logic of updating the filters had + been commented out. It was commented out because the previous logic deleted ALL + filters (including plugin filters) and re-created only the base filters. So in + effect, all plugin filters would be deleted whenever a filter checkbox was altered. + + So, we need some way of knowing which are the base filters so that we can take + action when a filter checkbox is marked [or unmarked]. Then we can update + the base filters by either deleting and recreating them, or by changing their + active state in an intelligent manner. I am choosing to do the latter. + + My goal here is to preserve the structure bfilter_t completely as it has been + historically. I feel that modifying bfilter_t is dangerous with respect to breaking + plugins. So what I'm doing instead is tracking which are the base filters via + external array, baseFilters. The array baseFilterExcludes keeps track of the "exclude" + parameter for the corresponding filter. +*/ + +#define MAX_BASE_FILTERS 32 +static bfilter_t *baseFilters[MAX_BASE_FILTERS]; +static int baseFilterExcludes[MAX_BASE_FILTERS]; +static int numBaseFilters = 0; + +// This shall not be called from outside filters.cpp. +bfilter_t *FilterAddImpl(bfilter_t *pFilter, int type, int bmask, const char *str, int exclude, bool baseFilter) { bfilter_t *pNew = new bfilter_t; pNew->next = pFilter; @@ -48,9 +72,29 @@ bfilter_t *FilterAdd(bfilter_t *pFilter, int type, int bmask, const char *str, i pNew->active = true; else pNew->active = false; + if (baseFilter) + { + if (numBaseFilters >= MAX_BASE_FILTERS) + Error("Base filters count exceeds MAX_BASE_FILTERS"); + baseFilters[numBaseFilters] = pNew; + baseFilterExcludes[numBaseFilters] = exclude; + numBaseFilters++; + } return pNew; } +// type 1 = texture filter (name) +// type 3 = entity filter (name) +// type 2 = QER_* shader flags +// type 4 = entity classes +// type 5 = surface flags (q2) +// type 6 = content flags (q2) +// type 7 = content flags - no match (q2) +bfilter_t *FilterAdd(bfilter_t *pFilter, int type, int bmask, const char *str, int exclude) +{ + return FilterAddImpl(pFilter, type, bmask, str, exclude, false); +} + bfilter_t *FilterCreate (int type, int bmask, const char *str, int exclude) { g_qeglobals.d_savedinfo.filters = FilterAdd(g_qeglobals.d_savedinfo.filters, type, bmask, str, exclude); @@ -67,6 +111,8 @@ void FiltersActivate (void) } // removes the filter list at *pFilter, returns NULL pointer +// IMPORTANT NOTE: Some plugins add filters, and those will be removed here as well. +// Therefore, this function should rarely be used. bfilter_t *FilterListDelete(bfilter_t *pFilter) { if (pFilter != NULL) @@ -74,31 +120,52 @@ bfilter_t *FilterListDelete(bfilter_t *pFilter) FilterListDelete(pFilter->next); delete pFilter; } + else + { + memset(baseFilters, 0, sizeof(baseFilters)); // Strictly speaking we don't really need this. + memset(baseFilterExcludes, 0, sizeof(baseFilterExcludes)); // Strictly speaking we don't really need this. + numBaseFilters = 0; // We do need this. + } return NULL; } - //spog - FilterUpdate is called each time the filters are changed by menu or shortcuts -bfilter_t *FilterUpdate(bfilter_t *pFilter) +bfilter_t *FilterAddBase(bfilter_t *pFilter) { - pFilter = FilterAdd(pFilter,1,0,"clip",EXCLUDE_CLIP); - pFilter = FilterAdd(pFilter,1,0,"caulk",EXCLUDE_CAULK); - pFilter = FilterAdd(pFilter,1,0,"liquids",EXCLUDE_LIQUIDS); - pFilter = FilterAdd(pFilter,1,0,"hint",EXCLUDE_HINTSSKIPS); - pFilter = FilterAdd(pFilter,1,0,"clusterportal",EXCLUDE_CLUSTERPORTALS); - pFilter = FilterAdd(pFilter,1,0,"areaportal",EXCLUDE_AREAPORTALS); - pFilter = FilterAdd(pFilter,2,QER_TRANS,NULL,EXCLUDE_TRANSLUCENT); - pFilter = FilterAdd(pFilter,3,0,"trigger",EXCLUDE_TRIGGERS); - pFilter = FilterAdd(pFilter,3,0,"misc_model",EXCLUDE_MODELS); - pFilter = FilterAdd(pFilter,3,0,"misc_gamemodel",EXCLUDE_MODELS); - pFilter = FilterAdd(pFilter,4,ECLASS_LIGHT,NULL,EXCLUDE_LIGHTS); - pFilter = FilterAdd(pFilter,4,ECLASS_PATH,NULL,EXCLUDE_PATHS); - pFilter = FilterAdd(pFilter,1,0,"lightgrid",EXCLUDE_LIGHTGRID); - pFilter = FilterAdd(pFilter,1,0,"botclip",EXCLUDE_BOTCLIP); - pFilter = FilterAdd(pFilter,1,0,"clipmonster",EXCLUDE_BOTCLIP); + pFilter = FilterAddImpl(pFilter,1,0,"clip",EXCLUDE_CLIP,true); + pFilter = FilterAddImpl(pFilter,1,0,"caulk",EXCLUDE_CAULK,true); + pFilter = FilterAddImpl(pFilter,1,0,"liquids",EXCLUDE_LIQUIDS,true); + pFilter = FilterAddImpl(pFilter,1,0,"hint",EXCLUDE_HINTSSKIPS,true); + pFilter = FilterAddImpl(pFilter,1,0,"clusterportal",EXCLUDE_CLUSTERPORTALS,true); + pFilter = FilterAddImpl(pFilter,1,0,"areaportal",EXCLUDE_AREAPORTALS,true); + pFilter = FilterAddImpl(pFilter,2,QER_TRANS,NULL,EXCLUDE_TRANSLUCENT,true); + pFilter = FilterAddImpl(pFilter,3,0,"trigger",EXCLUDE_TRIGGERS,true); + pFilter = FilterAddImpl(pFilter,3,0,"misc_model",EXCLUDE_MODELS,true); + pFilter = FilterAddImpl(pFilter,3,0,"misc_gamemodel",EXCLUDE_MODELS,true); + pFilter = FilterAddImpl(pFilter,4,ECLASS_LIGHT,NULL,EXCLUDE_LIGHTS,true); + pFilter = FilterAddImpl(pFilter,4,ECLASS_PATH,NULL,EXCLUDE_PATHS,true); + pFilter = FilterAddImpl(pFilter,1,0,"lightgrid",EXCLUDE_LIGHTGRID,true); + pFilter = FilterAddImpl(pFilter,1,0,"botclip",EXCLUDE_BOTCLIP,true); + pFilter = FilterAddImpl(pFilter,1,0,"clipmonster",EXCLUDE_BOTCLIP,true); return pFilter; } +void FilterUpdateBase() +{ + int i; + bfilter_t *filter; + int exclude; + for (i = 0; i < numBaseFilters; i++) + { + filter = baseFilters[i]; + exclude = baseFilterExcludes[i]; + if (g_qeglobals.d_savedinfo.exclude & exclude) + filter->active = true; + else + filter->active = false; + } +} + /* ================== FilterBrush diff --git a/radiant/filters.h b/radiant/filters.h index b6e8ebcf..3073dbde 100644 --- a/radiant/filters.h +++ b/radiant/filters.h @@ -26,7 +26,8 @@ void FiltersActivate(void); bfilter_t *FilterCreate(int type, int bmask, const char *str, int exclude); bfilter_t *FilterAdd(bfilter_t *pFilter, int type, int bmask, const char *str, int exclude); bfilter_t *FilterListDelete(bfilter_t *pFilter); -bfilter_t *FilterUpdate(bfilter_t *pFilter); +bfilter_t *FilterAddBase(bfilter_t *pFilter); +void FilterUpdateBase(); bool FilterBrush(brush_t *pb); #endif // _FILTERS_H_ diff --git a/radiant/main.cpp b/radiant/main.cpp index f1d3a0a5..a6e19296 100644 --- a/radiant/main.cpp +++ b/radiant/main.cpp @@ -932,7 +932,7 @@ int main( int argc, char* argv[] ) { // spog - creates new filters list for the first time g_qeglobals.d_savedinfo.filters = NULL; - g_qeglobals.d_savedinfo.filters = FilterUpdate(g_qeglobals.d_savedinfo.filters); + g_qeglobals.d_savedinfo.filters = FilterAddBase(g_qeglobals.d_savedinfo.filters); g_pParentWnd = new MainFrame(); diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 7f7dba22..b3d75c88 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -7505,14 +7505,7 @@ void PerformFiltering () { brush_t *brush; - // mattn - this should be removed - otherwise the filters from the - // plugins are wiped away with each update -#if 0 - // spog - deletes old filters list and creates new one when - // g_qeglobals.d_savedinfo.exclude is updated - g_qeglobals.d_savedinfo.filters = FilterListDelete(g_qeglobals.d_savedinfo.filters); - g_qeglobals.d_savedinfo.filters = FilterUpdate(g_qeglobals.d_savedinfo.filters); -#endif + FilterUpdateBase(); for ( brush = active_brushes.next; brush != &active_brushes; brush = brush->next ) brush->bFiltered = FilterBrush( brush ); -- 2.39.2