summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-10-22 19:54:10 -0700
committerRichard Linden <none@none>2012-10-22 19:54:10 -0700
commitd6634fcd2433e18eea1a9bf31da6d7e531817d77 (patch)
tree0d37227fd7424ef329f3dc3d642805a04b5c22b7 /indra/llcommon
parent534e0ee0514b482a8b32a72d5afed9a4652c0133 (diff)
SH-3405 WIP convert existing stats to lltrace system
sanitized param block code to accept isValid and isProvided at any point added predicates to control serialization
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llinitparam.cpp35
-rw-r--r--indra/llcommon/llinitparam.h221
-rw-r--r--indra/llcommon/llpredicate.cpp33
-rw-r--r--indra/llcommon/llpredicate.h173
-rw-r--r--indra/llcommon/llsdparam.cpp2
6 files changed, 376 insertions, 90 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index c0e9266aa9..d876842cf1 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -77,6 +77,7 @@ set(llcommon_SOURCE_FILES
llmutex.cpp
lloptioninterface.cpp
llptrto.cpp
+ llpredicate.cpp
llprocess.cpp
llprocessor.cpp
llqueuedthread.cpp
@@ -205,6 +206,7 @@ set(llcommon_HEADER_FILES
llnametable.h
lloptioninterface.h
llpointer.h
+ llpredicate.h
llpreprocessor.h
llpriqueuemap.h
llprocess.h
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index 54e98e66f3..a63e792925 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -164,24 +164,37 @@ namespace LLInitParam
bool BaseBlock::validateBlock(bool emit_errors) const
{
- const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
- for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
+ // only validate block when it hasn't already passed validation with current data
+ if (!mValidated)
{
- const Param* param = getParamFromHandle(it->first);
- if (!it->second(param))
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
+ for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
{
- if (emit_errors)
+ const Param* param = getParamFromHandle(it->first);
+ if (!it->second(param))
{
- llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
+ if (emit_errors)
+ {
+ llwarns << "Invalid param \"" << getParamName(block_data, param) << "\"" << llendl;
+ }
+ return false;
}
- return false;
}
+ mValidated = true;
}
- return true;
+ return mValidated;
}
- void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
+ void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const LLInitParam::BaseBlock* diff_block) const
{
+ if (!isProvided())
+ {
+ if ((~predicate_rule_t(PROVIDED) && predicate_rule).isTriviallyFalse())
+ {
+ return;
+ }
+ }
+
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
@@ -196,7 +209,7 @@ namespace LLInitParam
if (serialize_func)
{
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- serialize_func(*param, parser, name_stack, diff_param);
+ serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
}
}
@@ -232,7 +245,7 @@ namespace LLInitParam
name_stack.push_back(std::make_pair(it->first, !duplicate));
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
- serialize_func(*param, parser, name_stack, diff_param);
+ serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
name_stack.pop_back();
}
}
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index b7607e91b9..18c9669fba 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -32,10 +32,11 @@
#include <boost/function.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/unordered_map.hpp>
-#include <boost/shared_ptr.hpp>
+//#include <boost/shared_ptr.hpp>
#include "llerror.h"
#include "llstl.h"
+#include "llpredicate.h"
namespace LLInitParam
{
@@ -211,7 +212,6 @@ namespace LLInitParam
LOG_CLASS(Parser);
public:
-
typedef std::vector<std::pair<std::string, bool> > name_stack_t;
typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
typedef std::vector<std::string> possible_values_t;
@@ -293,6 +293,17 @@ namespace LLInitParam
class Param;
+ enum ESerializePredicates
+ {
+ PROVIDED,
+ REQUIRED,
+ VALID,
+ NON_DEFAULT
+ };
+
+ typedef LLPredicate::Rule<ESerializePredicates> predicate_rule_t;
+
+
// various callbacks and constraints associated with an individual param
struct LL_COMMON_API ParamDescriptor
{
@@ -303,8 +314,8 @@ namespace LLInitParam
typedef bool(*merge_func_t)(Param&, const Param&, bool);
typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
- typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
- typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
+ typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const predicate_rule_t, const Param*);
+ typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32, S32);
typedef bool(*validation_func_t)(const Param*);
ParamDescriptor(param_handle_t p,
@@ -331,7 +342,7 @@ namespace LLInitParam
UserData* mUserData;
};
- typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
+ typedef ParamDescriptor* ParamDescriptorPtr;
// each derived Block class keeps a static data structure maintaining offsets to various params
class LL_COMMON_API BlockDescriptor
@@ -484,12 +495,28 @@ namespace LLInitParam
LOG_CLASS(BaseBlock);
friend class Param;
+ BaseBlock()
+ : mValidated(false),
+ mParamProvided(false)
+ {}
+
virtual ~BaseBlock() {}
bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
param_handle_t getHandleFromParam(const Param* param) const;
bool validateBlock(bool emit_errors = true) const;
+ bool isProvided() const
+ {
+ return mParamProvided;
+ }
+
+ bool isValid() const
+ {
+ return validateBlock(false);
+ }
+
+
Param* getParamFromHandle(const param_handle_t param_handle)
{
if (param_handle == 0) return NULL;
@@ -507,10 +534,19 @@ namespace LLInitParam
void addSynonym(Param& param, const std::string& synonym);
// Blocks can override this to do custom tracking of changes
- virtual void paramChanged(const Param& changed_param, bool user_provided) {}
+ virtual void paramChanged(const Param& changed_param, bool user_provided)
+ {
+ if (user_provided)
+ {
+ // a child param has been explicitly changed
+ // so *some* aspect of this block is now provided
+ mValidated = false;
+ mParamProvided = true;
+ }
+ }
bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule = predicate_rule_t(), const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
@@ -549,6 +585,9 @@ namespace LLInitParam
return sBlockDescriptor;
}
+ mutable bool mValidated; // lazy validation flag
+ bool mParamProvided;
+
private:
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
@@ -688,13 +727,11 @@ namespace LLInitParam
typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
ParamValue()
- : T(),
- mValidated(false)
+ : T()
{}
ParamValue(value_assignment_t other)
- : T(other),
- mValidated(false)
+ : T(other)
{}
void setValue(value_assignment_t val)
@@ -736,9 +773,6 @@ namespace LLInitParam
return *this;
}
-
- protected:
- mutable bool mValidated; // lazy validation flag
};
template<typename NAME_VALUE_LOOKUP>
@@ -836,6 +870,8 @@ namespace LLInitParam
bool isProvided() const { return Param::anyProvided(); }
+ bool isValid() const { return true; }
+
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
self_t& typed_param = static_cast<self_t&>(param);
@@ -870,10 +906,26 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
+ const self_t* diff_typed_param = static_cast<const self_t*>(diff_param);
+
+ LLPredicate::Value<ESerializePredicates> predicate;
+ if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
+ {
+ predicate.set(NON_DEFAULT);
+ }
+ if (typed_param.isValid())
+ {
+ predicate.set(VALID);
+ if (typed_param.anyProvided())
+ {
+ predicate.set(PROVIDED);
+ }
+ }
+
+ if (!predicate_rule.check(predicate)) return;
if (!name_stack.empty())
{
@@ -886,18 +938,18 @@ namespace LLInitParam
if (!key.empty())
{
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
+ if (!diff_typed_param || !ParamCompare<std::string>::equals(diff_typed_param->getValueName(), key))
{
parser.writeValue(key, name_stack);
}
}
// then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
+ else if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
{
if (!parser.writeValue(typed_param.getValue(), name_stack))
{
std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
+ if (!diff_typed_param || !ParamCompare<std::string>::equals(diff_typed_param->getValueName(), calculated_key))
{
parser.writeValue(calculated_key, name_stack);
}
@@ -1014,10 +1066,26 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
- if (!typed_param.isProvided()) return;
+ const self_t* diff_typed_param = static_cast<const self_t*>(diff_param);
+
+ LLPredicate::Value<ESerializePredicates> predicate;
+ if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
+ {
+ predicate.set(NON_DEFAULT);
+ }
+ if (typed_param.isValid())
+ {
+ predicate.set(VALID);
+ if (typed_param.anyProvided())
+ {
+ predicate.set(PROVIDED);
+ }
+ }
+
+ if (!predicate_rule.check(predicate)) return;
if (!name_stack.empty())
{
@@ -1034,7 +1102,7 @@ namespace LLInitParam
}
else
{
- typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
+ typed_param.serializeBlock(parser, name_stack, predicate_rule, static_cast<const self_t*>(diff_param));
}
}
@@ -1049,23 +1117,16 @@ namespace LLInitParam
// *and* the block as a whole validates
bool isProvided() const
{
- // only validate block when it hasn't already passed validation with current data
- if (Param::anyProvided() && !param_value_t::mValidated)
- {
- // a sub-block is "provided" when it has been filled in enough to be valid
- param_value_t::mValidated = param_value_t::validateBlock(false);
- }
- return Param::anyProvided() && param_value_t::mValidated;
+ return Param::anyProvided() && isValid();
}
+ using param_value_t::isValid;
+
// assign block contents to this param-that-is-a-block
void set(value_assignment_t val, bool flag_as_provided = true)
{
setValue(val);
param_value_t::clearValueName();
- // force revalidation of block
- // next call to isProvided() will update provision status based on validity
- param_value_t::mValidated = false;
setProvided(flag_as_provided);
}
@@ -1080,9 +1141,6 @@ namespace LLInitParam
param_value_t::paramChanged(changed_param, user_provided);
if (user_provided)
{
- // a child param has been explicitly changed
- // so *some* aspect of this block is now provided
- param_value_t::mValidated = false;
setProvided();
param_value_t::clearValueName();
}
@@ -1134,7 +1192,9 @@ namespace LLInitParam
typedef NAME_VALUE_LOOKUP name_value_lookup_t;
TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mMinCount(min_count),
+ mMaxCount(max_count)
{
std::copy(value.begin(), value.end(), std::back_inserter(mValues));
@@ -1152,7 +1212,13 @@ namespace LLInitParam
}
}
- bool isProvided() const { return Param::anyProvided(); }
+ bool isProvided() const { return Param::anyProvided() && isValid(); }
+
+ bool isValid() const
+ {
+ size_t num_elements = numValidElements();
+ return mMinCount < num_elements && num_elements < mMaxCount;
+ }
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
@@ -1197,7 +1263,7 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided()) return;
@@ -1293,7 +1359,7 @@ namespace LLInitParam
bool empty() const { return mValues.empty(); }
size_t size() const { return mValues.size(); }
- U32 numValidElements() const
+ size_t numValidElements() const
{
return mValues.size();
}
@@ -1323,6 +1389,8 @@ namespace LLInitParam
}
container_t mValues;
+ size_t mMinCount,
+ mMaxCount;
};
// container of block parameters
@@ -1339,7 +1407,9 @@ namespace LLInitParam
typedef NAME_VALUE_LOOKUP name_value_lookup_t;
TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
- : Param(block_descriptor.mCurrentBlockPtr)
+ : Param(block_descriptor.mCurrentBlockPtr),
+ mMinCount(min_count),
+ mMaxCount(max_count)
{
std::copy(value.begin(), value.end(), back_inserter(mValues));
@@ -1357,7 +1427,14 @@ namespace LLInitParam
}
}
- bool isProvided() const { return Param::anyProvided(); }
+ bool isProvided() const { return Param::anyProvided() && isValid(); }
+
+ bool isValid() const
+ {
+ size_t num_elements = numValidElements();
+ return mMinCount < num_elements && num_elements < mMaxCount;
+ }
+
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
{
@@ -1420,9 +1497,13 @@ namespace LLInitParam
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
+
+ LLPredicate::Value<ESerializePredicates> predicate_value;
+ if (typed_param.isProvided()) predicate_value.set(PROVIDED);
+
if (!typed_param.isProvided()) return;
for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
@@ -1437,10 +1518,10 @@ namespace LLInitParam
parser.writeValue(key, name_stack);
}
// Not parsed via named values, write out value directly
- // NOTE: currently we don't worry about removing default values in Multiple
+ // NOTE: currently we don't do diffing of Multiples
else
{
- it->serializeBlock(parser, name_stack, NULL);
+ it->serializeBlock(parser, name_stack, predicate_rule, NULL);
}
name_stack.pop_back();
@@ -1500,14 +1581,14 @@ namespace LLInitParam
bool empty() const { return mValues.empty(); }
size_t size() const { return mValues.size(); }
- U32 numValidElements() const
+ size_t numValidElements() const
{
- U32 count = 0;
+ size_t count = 0;
for (const_iterator it = mValues.begin(), end_it = mValues.end();
it != end_it;
++it)
{
- if(it->validateBlock(false)) count++;
+ if(it->isValid()) count++;
}
return count;
}
@@ -1539,6 +1620,8 @@ namespace LLInitParam
}
container_t mValues;
+ size_t mMinCount,
+ mMaxCount;
};
template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
@@ -1826,7 +1909,7 @@ namespace LLInitParam
static bool validate(const Param* paramp)
{
- U32 num_valid = ((super_t*)paramp)->numValidElements();
+ size_t num_valid = ((super_t*)paramp)->numValidElements();
return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
}
};
@@ -1943,13 +2026,11 @@ namespace LLInitParam
typedef block_t value_t;
ParamValue()
- : block_t(),
- mValidated(false)
+ : block_t()
{}
ParamValue(value_assignment_t other)
- : block_t(other),
- mValidated(false)
+ : block_t(other)
{
}
@@ -1977,9 +2058,6 @@ namespace LLInitParam
{
return *this;
}
-
- protected:
- mutable bool mValidated; // lazy validation flag
};
template<typename T, bool IS_BLOCK>
@@ -1994,13 +2072,11 @@ namespace LLInitParam
typedef T value_t;
ParamValue()
- : mValue(),
- mValidated(false)
+ : mValue()
{}
ParamValue(value_assignment_t other)
- : mValue(other),
- mValidated(false)
+ : mValue(other)
{}
void setValue(value_assignment_t val)
@@ -2033,11 +2109,11 @@ namespace LLInitParam
return mValue.get().deserializeBlock(p, name_stack_range, new_name);
}
- void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const
{
if (mValue.empty()) return;
- mValue.get().serializeBlock(p, name_stack, diff_block);
+ mValue.get().serializeBlock(p, name_stack, predicate_rule, diff_block);
}
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
@@ -2047,9 +2123,6 @@ namespace LLInitParam
return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
}
- protected:
- mutable bool mValidated; // lazy validation flag
-
private:
BaseBlock::Lazy<T> mValue;
};
@@ -2066,12 +2139,10 @@ namespace LLInitParam
typedef const LLSD& value_assignment_t;
ParamValue()
- : mValidated(false)
{}
ParamValue(value_assignment_t other)
- : mValue(other),
- mValidated(false)
+ : mValue(other)
{}
void setValue(value_assignment_t val) { mValue = val; }
@@ -2085,16 +2156,13 @@ namespace LLInitParam
// block param interface
LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
- LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
+ LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
//TODO: implement LLSD params as schema type Any
return true;
}
- protected:
- mutable bool mValidated; // lazy validation flag
-
private:
static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
@@ -2123,8 +2191,7 @@ namespace LLInitParam
CustomParamValue(const T& value = T())
: mValue(value),
- mValueAge(VALUE_AUTHORITATIVE),
- mValidated(false)
+ mValueAge(VALUE_AUTHORITATIVE)
{}
bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
@@ -2148,7 +2215,7 @@ namespace LLInitParam
return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
}
- void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const
{
const derived_t& typed_param = static_cast<const derived_t&>(*this);
const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
@@ -2184,11 +2251,11 @@ namespace LLInitParam
// and serialize those params
derived_t copy(typed_param);
copy.updateBlockFromValue(true);
- copy.block_t::serializeBlock(parser, name_stack, NULL);
+ copy.block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);
}
else
{
- block_t::serializeBlock(parser, name_stack, NULL);
+ block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);
}
}
}
@@ -2309,8 +2376,6 @@ namespace LLInitParam
return block_t::mergeBlock(block_data, source, overwrite);
}
- mutable bool mValidated; // lazy validation flag
-
private:
mutable T mValue;
mutable EValueAge mValueAge;
diff --git a/indra/llcommon/llpredicate.cpp b/indra/llcommon/llpredicate.cpp
new file mode 100644
index 0000000000..8dcd9247b7
--- /dev/null
+++ b/indra/llcommon/llpredicate.cpp
@@ -0,0 +1,33 @@
+/**
+ * @file llpredicate.cpp
+ * @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llpredicate.h"
+
+namespace LLPredicate
+{
+ EmptyRule make_rule() { return EmptyRule(); }
+}
diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h
new file mode 100644
index 0000000000..ad5ab363fa
--- /dev/null
+++ b/indra/llcommon/llpredicate.h
@@ -0,0 +1,173 @@
+/**
+ * @file llpredicate.h
+ * @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPREDICATE_H
+#define LL_LLPREDICATE_H
+
+#include "llerror.h"
+
+namespace LLPredicate
+{
+ template<typename ENUM> class Rule;
+
+ template<typename ENUM>
+ struct Value
+ {
+ friend Rule<ENUM>;
+ public:
+ Value(ENUM e)
+ : mPredicateFlags(0x1),
+ mPredicateCombinationFlags(0x1)
+ {
+ set(e);
+ }
+
+ Value()
+ : mPredicateFlags(0x1),
+ mPredicateCombinationFlags(0x1)
+ {}
+
+ void set(ENUM predicate)
+ {
+ llassert(predicate <= 5);
+ int predicate_flag = 0x1 << (0x1 << (int)predicate);
+ if (!(mPredicateFlags & predicate_flag))
+ {
+ mPredicateCombinationFlags *= predicate_flag;
+ mPredicateFlags |= predicate_flag;
+ }
+ }
+
+ bool get(ENUM predicate)
+ {
+ int predicate_flag = 0x1 << (0x1 << (int)predicate);
+ return (mPredicateFlags & predicate_flag) != 0;
+ }
+
+ void clear(ENUM predicate)
+ {
+ llassert(predicate <= 5);
+ int predicate_flag = 0x1 << (0x1 << (int)predicate);
+ if (mPredicateFlags & predicate_flag)
+ {
+ mPredicateCombinationFlags /= predicate_flag;
+ mPredicateFlags &= ~predicate_flag;
+ }
+ }
+
+ private:
+ int mPredicateCombinationFlags;
+ int mPredicateFlags;
+ };
+
+ struct EmptyRule {};
+
+ template<typename ENUM>
+ class Rule
+ {
+ public:
+ Rule(EmptyRule e)
+ : mPredicateRequirements(0x1)
+ {}
+
+ Rule(ENUM value)
+ : mPredicateRequirements(predicateFromValue(value))
+ {}
+
+ Rule()
+ : mPredicateRequirements(0x1)
+ {}
+
+ Rule operator~()
+ {
+ Rule new_rule;
+ new_rule.mPredicateRequirements = ~mPredicateRequirements;
+ return new_rule;
+ }
+
+ Rule operator &&(const Rule& other)
+ {
+ Rule new_rule;
+ new_rule.mPredicateRequirements = mPredicateRequirements & other.mPredicateRequirements;
+ return new_rule;
+ }
+
+ Rule operator ||(const Rule& other)
+ {
+ Rule new_rule;
+ new_rule.mPredicateRequirements = mPredicateRequirements | other.mPredicateRequirements;
+ return new_rule;
+ }
+
+ bool check(const Value<ENUM>& value) const
+ {
+ return ((value.mPredicateCombinationFlags | 0x1) & mPredicateRequirements) != 0;
+ }
+
+ static int predicateFromValue(ENUM value)
+ {
+ int countdown = value;
+ bool bit_val = false;
+
+ int predicate = 0x0;
+
+ for (int bit_index = 0; bit_index < 32; bit_index++)
+ {
+ if (bit_val)
+ {
+ predicate |= 0x1 << bit_index;
+ }
+
+ if (countdown-- == 0)
+ {
+ countdown = value;
+ bit_val = !bit_val;
+ }
+ }
+ return predicate;
+ }
+
+ bool isTriviallyTrue() const
+ {
+ return mPredicateRequirements & 0x1;
+ }
+
+ bool isTriviallyFalse() const
+ {
+ return mPredicateRequirements == 0;
+ }
+
+ private:
+ int mPredicateRequirements;
+ };
+
+ template<typename ENUM>
+ Rule<ENUM> make_rule(ENUM e) { return Rule<ENUM>(e);}
+
+ EmptyRule make_rule();
+
+}
+#endif // LL_LLPREDICATE_H
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 4b8a8dba5c..713f5ac605 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -329,7 +329,7 @@ namespace LLInitParam
p.writeValue<LLSD::String>(sd.asString(), name_stack);
}
- void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+ void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block) const
{
// attempt to write LLSD out directly
if (!p.writeValue<LLSD>(mValue, name_stack))