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
This commit is contained in:
rambetter 2011-01-23 09:12:34 +00:00
parent 9aa5e96c63
commit 3d4ac1ba23
4 changed files with 96 additions and 35 deletions

View file

@ -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

View file

@ -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_

View file

@ -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();

View file

@ -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 );