summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2011-04-22 11:49:41 -0400
committerOz Linden <oz@lindenlab.com>2011-04-22 11:49:41 -0400
commit0656620e2d6b4b9ca1fabf4f045df77256f31a60 (patch)
tree0480f0c03bb4fbf3fd526aaa061715ab20ac4f22
parentb15dca22637b0b2c1947b758a93f51163fb48cf1 (diff)
parent8c4555d54fc7c8686ffd139425f4c346576cac50 (diff)
merge changes for storm-1187
-rw-r--r--indra/cmake/Variables.cmake2
-rw-r--r--indra/integration_tests/llimage_libtest/llimage_libtest.cpp193
-rw-r--r--indra/llimage/llimage.cpp23
-rw-r--r--indra/llimage/llimagej2c.cpp12
-rw-r--r--indra/llimage/llimagej2c.h4
-rw-r--r--indra/llimagej2coj/llimagej2coj.cpp11
-rw-r--r--indra/llimagej2coj/llimagej2coj.h2
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp499
-rw-r--r--indra/llkdu/llimagej2ckdu.h6
-rw-r--r--indra/llkdu/llkdumem.cpp22
-rw-r--r--indra/llkdu/llkdumem.h44
-rw-r--r--indra/llui/llloadingindicator.cpp67
-rw-r--r--indra/llui/llloadingindicator.h30
-rw-r--r--indra/llui/llui.cpp103
-rw-r--r--indra/llui/llui.h79
-rw-r--r--indra/llui/lluiimage.cpp12
-rw-r--r--indra/llui/lluiimage.h17
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp34
-rw-r--r--indra/llui/tests/llurlentry_test.cpp16
-rw-r--r--indra/llui/tests/llurlmatch_test.cpp52
-rw-r--r--indra/llxuixml/llinitparam.cpp101
-rw-r--r--indra/llxuixml/llinitparam.h1139
-rw-r--r--indra/newview/app_settings/settings.xml33
-rw-r--r--indra/newview/app_settings/settings_minimal.xml33
-rw-r--r--indra/newview/llappearancemgr.cpp6
-rw-r--r--indra/newview/llfloaterimagepreview.cpp119
-rw-r--r--indra/newview/llfloatersearch.cpp7
-rw-r--r--indra/newview/lllogininstance.cpp12
-rw-r--r--indra/newview/llpreviewtexture.cpp34
-rw-r--r--indra/newview/llsidetray.cpp99
-rw-r--r--indra/newview/llsidetray.h2
-rw-r--r--indra/newview/lltoolpie.cpp1
-rw-r--r--indra/newview/llviewerinventory.cpp6
-rw-r--r--indra/newview/llviewermenufile.cpp55
-rw-r--r--indra/newview/llviewertexturelist.cpp110
-rw-r--r--indra/newview/llviewerwindow.cpp154
-rw-r--r--indra/newview/skins/default/colors.xml17
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml44
-rw-r--r--indra/newview/skins/default/xui/en/panel_bottomtray.xml614
-rw-r--r--indra/newview/skins/default/xui/en/widgets/loading_indicator.xml20
-rw-r--r--indra/newview/skins/minimal/xui/en/panel_bottomtray.xml6
-rw-r--r--indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml64
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.cpp4
43 files changed, 2106 insertions, 1802 deletions
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 8c9c375790..03428691cf 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -102,7 +102,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.2")
- set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "DWARF with dSYM File")
+ set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
# -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc'
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index 365f5f758c..60ddf63b21 100644
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -53,12 +53,32 @@ static const char USAGE[] = "\n"
" -o, --output <file1 .. file2> OR <type>\n"
" List of image files to create (assumes same order as for input files)\n"
" OR 3 letters file type extension to convert each input file into.\n"
+" -r, --region <x0, y0, x1, y1>\n"
+" Crop region applied to the input files in pixels.\n"
+" Only used for j2c images. Default is no region cropping.\n"
+" -d, --discard_level <n>\n"
+" Discard level max used on input. 0 is highest resolution. Max discard level is 5.\n"
+" This allows the input image to be clamped in resolution when loading.\n"
+" Only valid for j2c images. Default is no discard.\n"
+" -p, --precincts <n>\n"
+" Dimension of precincts in pixels. Precincts are assumed square and identical for\n"
+" all levels. Note that this option also add PLT and tile markers to the codestream, \n"
+" and uses RPCL order. Power of 2 must be used.\n"
+" Only valid for output j2c images. Default is no precincts used.\n"
+" -b, --blocks <n>\n"
+" Dimension of coding blocks in pixels. Blocks are assumed square. Power of 2 must\n"
+" be used. Blocks must be smaller than precincts. Like precincts, this option adds\n"
+" PLT, tile markers and uses RPCL.\n"
+" Only valid for output j2c images. Default is 64.\n"
+" -rev, --reversible\n"
+" Set the compression to be lossless (reversible in j2c parlance).\n"
+" Only valid for output j2c images.\n"
" -log, --logmetrics <metric>\n"
" Log performance data for <metric>. Results in <metric>.slp\n"
" Note: so far, only ImageCompressionTester has been tested.\n"
-" -r, --analyzeperformance\n"
+" -a, --analyzeperformance\n"
" Create a report comparing <metric>_baseline.slp with current <metric>.slp\n"
-" Results in <metric>_report.csv"
+" Results in <metric>_report.csv\n"
" -s, --image-stats\n"
" Output stats for each input and output image.\n"
"\n";
@@ -69,31 +89,8 @@ static bool sAllDone = false;
// Create an empty formatted image instance of the correct type from the filename
LLPointer<LLImageFormatted> create_image(const std::string &filename)
{
- std::string exten = gDirUtilp->getExtension(filename);
- U32 codec = LLImageBase::getCodecFromExtension(exten);
-
- LLPointer<LLImageFormatted> image;
- switch (codec)
- {
- case IMG_CODEC_BMP:
- image = new LLImageBMP();
- break;
- case IMG_CODEC_TGA:
- image = new LLImageTGA();
- break;
- case IMG_CODEC_JPEG:
- image = new LLImageJPEG();
- break;
- case IMG_CODEC_J2C:
- image = new LLImageJ2C();
- break;
- case IMG_CODEC_PNG:
- image = new LLImagePNG();
- break;
- default:
- return NULL;
- }
-
+ std::string exten = gDirUtilp->getExtension(filename);
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromExtension(exten);
return image;
}
@@ -110,10 +107,11 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi
}
// Load an image from file and return a raw (decompressed) instance of its data
-LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_stats)
+LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, bool output_stats)
{
LLPointer<LLImageFormatted> image = create_image(src_filename);
-
+
+ // This just loads the image file stream into a buffer. No decoding done.
if (!image->load(src_filename))
{
return NULL;
@@ -131,6 +129,15 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_st
}
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
+
+ // Set the image restriction on load in the case of a j2c image
+ if ((image->getCodec() == IMG_CODEC_J2C) && ((discard_level != -1) || (region != NULL)))
+ {
+ // That method doesn't exist (and likely, doesn't make sense) for any other image file format
+ // hence the required cryptic cast.
+ ((LLImageJ2C*)(image.get()))->initDecode(*raw_image, discard_level, region);
+ }
+
if (!image->decode(raw_image, 0.0f))
{
return NULL;
@@ -140,10 +147,22 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_st
}
// Save a raw image instance into a file
-bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, bool output_stats)
+bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, bool reversible, bool output_stats)
{
LLPointer<LLImageFormatted> image = create_image(dest_filename);
+ // Set the image codestream parameters on output in the case of a j2c image
+ if (image->getCodec() == IMG_CODEC_J2C)
+ {
+ // That method doesn't exist (and likely, doesn't make sense) for any other image file format
+ // hence the required cryptic cast.
+ if ((blocks_size != -1) || (precincts_size != -1))
+ {
+ ((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size);
+ }
+ ((LLImageJ2C*)(image.get()))->setReversible(reversible);
+ }
+
if (!image->encode(raw_image, 0.0f))
{
return false;
@@ -280,8 +299,14 @@ int main(int argc, char** argv)
// List of input and output files
std::list<std::string> input_filenames;
std::list<std::string> output_filenames;
+ // Other optional parsed arguments
bool analyze_performance = false;
bool image_stats = false;
+ int* region = NULL;
+ int discard_level = -1;
+ int precincts_size = -1;
+ int blocks_size = -1;
+ bool reversible = false;
// Init whatever is necessary
ll_init_apr();
@@ -323,6 +348,85 @@ int main(int argc, char** argv)
file_name = argv[arg+1]; // Next argument and loop over
}
}
+ else if ((!strcmp(argv[arg], "--region") || !strcmp(argv[arg], "-r")) && arg < argc-1)
+ {
+ std::string value_str = argv[arg+1];
+ int index = 0;
+ region = new int[4];
+ while (value_str[0] != '-') // if arg starts with '-', it's the next option
+ {
+ int value = atoi(value_str.c_str());
+ region[index++] = value;
+ arg += 1; // Definitely skip that arg now we know it's a number
+ if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list
+ break;
+ if (index == 4) // Break out of the loop if we captured 4 values already
+ break;
+ value_str = argv[arg+1]; // Next argument and loop over
+ }
+ if (index != 4)
+ {
+ std::cout << "--region arguments invalid" << std::endl;
+ delete [] region;
+ region = NULL;
+ }
+ }
+ else if (!strcmp(argv[arg], "--discard_level") || !strcmp(argv[arg], "-d"))
+ {
+ std::string value_str;
+ if ((arg + 1) < argc)
+ {
+ value_str = argv[arg+1];
+ }
+ if (((arg + 1) >= argc) || (value_str[0] == '-'))
+ {
+ std::cout << "No valid --discard_level argument given, discard_level ignored" << std::endl;
+ }
+ else
+ {
+ discard_level = atoi(value_str.c_str());
+ // Clamp to the values accepted by the viewer
+ discard_level = llclamp(discard_level,0,5);
+ }
+ }
+ else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p"))
+ {
+ std::string value_str;
+ if ((arg + 1) < argc)
+ {
+ value_str = argv[arg+1];
+ }
+ if (((arg + 1) >= argc) || (value_str[0] == '-'))
+ {
+ std::cout << "No valid --precincts argument given, precincts ignored" << std::endl;
+ }
+ else
+ {
+ precincts_size = atoi(value_str.c_str());
+ // *TODO: make sure precincts_size is a power of 2
+ }
+ }
+ else if (!strcmp(argv[arg], "--blocks") || !strcmp(argv[arg], "-b"))
+ {
+ std::string value_str;
+ if ((arg + 1) < argc)
+ {
+ value_str = argv[arg+1];
+ }
+ if (((arg + 1) >= argc) || (value_str[0] == '-'))
+ {
+ std::cout << "No valid --blocks argument given, blocks ignored" << std::endl;
+ }
+ else
+ {
+ blocks_size = atoi(value_str.c_str());
+ // *TODO: make sure blocks_size is a power of 2
+ }
+ }
+ else if (!strcmp(argv[arg], "--reversible") || !strcmp(argv[arg], "-rev"))
+ {
+ reversible = true;
+ }
else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log"))
{
// '--logmetrics' needs to be specified with a named test metric argument
@@ -346,7 +450,7 @@ int main(int argc, char** argv)
break;
}
}
- else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-r"))
+ else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a"))
{
analyze_performance = true;
}
@@ -364,7 +468,7 @@ int main(int argc, char** argv)
}
if (analyze_performance && !LLFastTimer::sMetricLog)
{
- std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -r) -> exit" << std::endl;
+ std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -a) -> exit" << std::endl;
return 0;
}
@@ -382,10 +486,10 @@ int main(int argc, char** argv)
std::list<std::string>::iterator out_file = output_filenames.begin();
std::list<std::string>::iterator in_end = input_filenames.end();
std::list<std::string>::iterator out_end = output_filenames.end();
- for (; in_file != in_end; ++in_file)
+ for (; in_file != in_end; ++in_file, ++out_file)
{
// Load file
- LLPointer<LLImageRaw> raw_image = load_image(*in_file, image_stats);
+ LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);
if (!raw_image)
{
std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
@@ -395,7 +499,7 @@ int main(int argc, char** argv)
// Save file
if (out_file != out_end)
{
- if (!save_image(*out_file, raw_image, image_stats))
+ if (!save_image(*out_file, raw_image, blocks_size, precincts_size, reversible, image_stats))
{
std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;
}
@@ -403,29 +507,28 @@ int main(int argc, char** argv)
{
std::cout << *in_file << " -> " << *out_file << std::endl;
}
- ++out_file;
}
}
- // Stop the perf gathering system if needed
- if (LLFastTimer::sMetricLog)
- {
- LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName);
- sAllDone = true;
- }
-
// Output perf data if requested by user
if (analyze_performance)
{
- std::cout << "Analyzing performance" << std::endl;
-
std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
std::string current_name = LLFastTimer::sLogName + ".slp";
std::string report_name = LLFastTimer::sLogName + "_report.csv";
+ std::cout << "Analyzing performance, check report in : " << report_name << std::endl;
+
LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name);
}
+ // Stop the perf gathering system if needed
+ if (LLFastTimer::sMetricLog)
+ {
+ LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName);
+ sAllDone = true;
+ }
+
// Cleanup and exit
LLImage::cleanupClass();
if (fast_timer_log_thread)
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 39211bf7fa..f0d15d9607 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1254,28 +1254,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
return false;
}
- LLPointer<LLImageFormatted> image;
- switch(codec)
- {
- //case IMG_CODEC_RGB:
- case IMG_CODEC_BMP:
- image = new LLImageBMP();
- break;
- case IMG_CODEC_TGA:
- image = new LLImageTGA();
- break;
- case IMG_CODEC_JPEG:
- image = new LLImageJPEG();
- break;
- case IMG_CODEC_J2C:
- image = new LLImageJ2C();
- break;
- case IMG_CODEC_DXT:
- image = new LLImageDXT();
- break;
- default:
- return false;
- }
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
llassert(image.notNull());
U8 *buffer = image->allocateData(length);
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 80fec7f8a0..a90df0f1c1 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -139,6 +139,15 @@ BOOL LLImageJ2C::updateData()
return res;
}
+BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region)
+{
+ return mImpl->initDecode(*this,raw_image,discard_level,region);
+}
+
+BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size)
+{
+ return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size);
+}
BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
{
@@ -251,6 +260,9 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()
//static
S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)
{
+ // Note: this only provides an *estimate* of the size in bytes of an image level
+ // *TODO: find a way to read the true size (when available) and convey the fact
+ // that the result is an estimate in the other cases
if (rate <= 0.f) rate = .125f;
while (discard_level > 0)
{
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index dd5bec8b2e..6bba81aab5 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -56,6 +56,8 @@ public:
/*virtual*/ void resetLastError();
/*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string());
+ BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region);
+ BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size);
// Encode with comment text
BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0);
@@ -117,6 +119,8 @@ protected:
virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;
virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
BOOL reversible=FALSE) = 0;
+ virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0;
+ virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1) = 0;
friend class LLImageJ2C;
};
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 13b12c0928..8288fa1f5c 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -107,6 +107,17 @@ LLImageJ2COJ::~LLImageJ2COJ()
{
}
+BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
+{
+ // No specific implementation for this method in the OpenJpeg case
+ return FALSE;
+}
+
+BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size)
+{
+ // No specific implementation for this method in the OpenJpeg case
+ return FALSE;
+}
BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
{
diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h
index 9476665ccb..9c7cc09fcb 100644
--- a/indra/llimagej2coj/llimagej2coj.h
+++ b/indra/llimagej2coj/llimagej2coj.h
@@ -39,6 +39,8 @@ protected:
/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
BOOL reversible = FALSE);
+ /*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
+ /*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);
};
#endif
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 10ea5685e8..ae456a48be 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -34,35 +34,35 @@
class kdc_flow_control {
-public: // Member functions
- kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream);
- ~kdc_flow_control();
- bool advance_components();
- void process_components();
+public:
+ kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream);
+ ~kdc_flow_control();
+ bool advance_components();
+ void process_components();
+
+private:
-private: // Data
-
- struct kdc_component_flow_control {
- public: // Data
- kdu_image_in_base *reader;
- int vert_subsampling;
- int ratio_counter; /* Initialized to 0, decremented by `count_delta';
+ struct kdc_component_flow_control {
+ public:
+ kdu_image_in_base *reader;
+ int vert_subsampling;
+ int ratio_counter; /* Initialized to 0, decremented by `count_delta';
when < 0, a new line must be processed, after
which it is incremented by `vert_subsampling'. */
- int initial_lines;
- int remaining_lines;
- kdu_line_buf *line;
- };
-
- kdu_codestream codestream;
- kdu_dims valid_tile_indices;
- kdu_coords tile_idx;
- kdu_tile tile;
- int num_components;
- kdc_component_flow_control *components;
- int count_delta; // Holds the minimum of the `vert_subsampling' fields
- kdu_multi_analysis engine;
- kdu_long max_buffer_memory;
+ int initial_lines;
+ int remaining_lines;
+ kdu_line_buf *line;
+ };
+
+ kdu_codestream codestream;
+ kdu_dims valid_tile_indices;
+ kdu_coords tile_idx;
+ kdu_tile tile;
+ int num_components;
+ kdc_component_flow_control *components;
+ int count_delta; // Holds the minimum of the `vert_subsampling' fields
+ kdu_multi_analysis engine;
+ kdu_long max_buffer_memory;
};
//
@@ -72,7 +72,8 @@ void set_default_colour_weights(kdu_params *siz);
const char* engineInfoLLImageJ2CKDU()
{
- return "KDU v6.4.1";
+ std::string version = llformat("KDU %s", KDU_CORE_VERSION);
+ return version.c_str();
}
LLImageJ2CKDU* createLLImageJ2CKDU()
@@ -105,7 +106,11 @@ const char* fallbackEngineInfoLLImageJ2CImpl()
class LLKDUDecodeState
{
public:
+ LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap);
+ ~LLKDUDecodeState();
+ BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE);
+private:
S32 mNumComponents;
BOOL mUseYCC;
kdu_dims mDims;
@@ -113,22 +118,12 @@ public:
kdu_tile_comp mComps[4];
kdu_line_buf mLines[4];
kdu_pull_ifc mEngines[4];
- bool mReversible[4]; // Some components may be reversible and others not.
- int mBitDepths[4]; // Original bit-depth may be quite different from 8.
-
+ bool mReversible[4]; // Some components may be reversible and others not
+ int mBitDepths[4]; // Original bit-depth may be quite different from 8
+
kdu_tile mTile;
kdu_byte *mBuf;
S32 mRowGap;
-
- LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap);
- ~LLKDUDecodeState();
- BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE);
-
-public:
- int *AssignLayerBytes(siz_params *siz, int &num_specs);
-
- void setupCodeStream(BOOL keep_codestream, LLImageJ2CKDU::ECodeStreamMode mode);
- BOOL initDecode(LLImageRaw &raw_image, F32 decode_time, LLImageJ2CKDU::ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );
};
void ll_kdu_error( void )
@@ -153,7 +148,7 @@ class LLKDUMessageError : public kdu_message
public:
/*virtual*/ void put_text(const char *s);
/*virtual*/ void put_text(const kdu_uint16 *s);
- /*virtual*/ void flush(bool end_of_message=false);
+ /*virtual*/ void flush(bool end_of_message = false);
static LLKDUMessageError sDefaultMessage;
};
@@ -179,7 +174,7 @@ void LLKDUMessageError::put_text(const kdu_uint16 *s)
void LLKDUMessageError::flush(bool end_of_message)
{
- if( end_of_message )
+ if (end_of_message)
{
throw "KDU throwing an exception";
}
@@ -195,7 +190,9 @@ mCodeStreamp(NULL),
mTPosp(NULL),
mTileIndicesp(NULL),
mRawImagep(NULL),
-mDecodeState(NULL)
+mDecodeState(NULL),
+mBlocksSize(-1),
+mPrecinctsSize(-1)
{
}
@@ -210,7 +207,7 @@ void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);
void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode)
{
S32 data_size = base.getDataSize();
- S32 max_bytes = base.getMaxBytes() ? base.getMaxBytes() : data_size;
+ S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
//
// Initialization
@@ -247,21 +244,21 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
// Set the maximum number of bytes to use from the codestream
mCodeStreamp->set_max_bytes(max_bytes);
- // If you want to flip or rotate the image for some reason, change
+ // If you want to flip or rotate the image for some reason, change
// the resolution, or identify a restricted region of interest, this is
// the place to do it. You may use "kdu_codestream::change_appearance"
// and "kdu_codestream::apply_input_restrictions" for this purpose.
- // If you wish to truncate the code-stream prior to decompression, you
+ // If you wish to truncate the code-stream prior to decompression, you
// may use "kdu_codestream::set_max_bytes".
- // If you wish to retain all compressed data so that the material
+ // If you wish to retain all compressed data so that the material
// can be decompressed multiple times, possibly with different appearance
// parameters, you should call "kdu_codestream::set_persistent" here.
- // There are a variety of other features which must be enabled at
+ // There are a variety of other features which must be enabled at
// this point if you want to take advantage of them. See the
// descriptions appearing with the "kdu_codestream" interface functions
// in "kdu_compressed.h" for an itemized account of these capabilities.
- switch( mode )
+ switch (mode)
{
case MODE_FAST:
mCodeStreamp->set_fast();
@@ -326,7 +323,19 @@ void LLImageJ2CKDU::cleanupCodeStream()
mTileIndicesp = NULL;
}
-BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count )
+BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
+{
+ return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region);
+}
+
+BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size)
+{
+ mBlocksSize = blocks_size;
+ mPrecinctsSize = precincts_size;
+ return TRUE;
+}
+
+BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
{
base.resetLastError();
@@ -339,17 +348,36 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
mRawImagep = &raw_image;
mCodeStreamp->change_appearance(false, true, false);
- mCodeStreamp->apply_input_restrictions(first_channel,max_channel_count,base.getRawDiscardLevel(),0,NULL);
- kdu_dims dims; mCodeStreamp->get_dims(0,dims);
- S32 channels = base.getComponents() - first_channel;
- if( channels > max_channel_count )
+ // Apply loading discard level and cropping if required
+ kdu_dims* region_kdu = NULL;
+ if (region != NULL)
{
- channels = max_channel_count;
+ region_kdu = new kdu_dims;
+ region_kdu->pos.x = region[0];
+ region_kdu->pos.y = region[1];
+ region_kdu->size.x = region[2] - region[0];
+ region_kdu->size.y = region[3] - region[1];
}
+ int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel());
+
+ // Apply loading restrictions
+ mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu);
+
+ // Clean-up
+ if (region_kdu)
+ {
+ delete region_kdu;
+ region_kdu = NULL;
+ }
+
+ // Resize raw_image according to the image to be decoded
+ kdu_dims dims; mCodeStreamp->get_dims(0,dims);
+ S32 channels = base.getComponents() - first_channel;
+ channels = llmin(channels,max_channel_count);
raw_image.resize(dims.size.x, dims.size.y, channels);
+ // llinfos << "Resizing raw_image to " << dims.size.x << ":" << dims.size.y << llendl;
- // llinfos << "Resizing to " << dims.size.x << ":" << dims.size.y << llendl;
if (!mTileIndicesp)
{
mTileIndicesp = new kdu_dims;
@@ -426,7 +454,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
// canvas coordinate system. Comparing the two tells
// us where the current tile is in the buffer.
S32 channels = base.getComponents() - first_channel;
- if( channels > max_channel_count )
+ if (channels > max_channel_count)
{
channels = max_channel_count;
}
@@ -452,14 +480,14 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
return FALSE;
}
}
- catch( const char* msg )
+ catch (const char* msg)
{
base.setLastError(ll_safe_string(msg));
base.decodeFailed();
cleanupCodeStream();
return TRUE; // done
}
- catch( ... )
+ catch (...)
{
base.setLastError( "Unknown J2C error" );
base.decodeFailed();
@@ -482,28 +510,17 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
{
- // Collect simple arguments.
- bool transpose, vflip, hflip;
- bool allow_rate_prediction, mem, quiet, no_weights;
- int cpu_iterations;
- std::ostream *record_stream;
-
- transpose = false;
- record_stream = NULL;
- allow_rate_prediction = true;
- no_weights = false;
- cpu_iterations = -1;
- mem = false;
- quiet = false;
- vflip = true;
- hflip = false;
+ // Declare and set simple arguments
+ bool transpose = false;
+ bool vflip = true;
+ bool hflip = false;
try
{
- // Set up input image files.
+ // Set up input image files
siz_params siz;
- // Should set rate someplace here.
+ // Should set rate someplace here
LLKDUMemIn mem_in(raw_image.getData(),
raw_image.getDataSize(),
raw_image.getWidth(),
@@ -521,26 +538,17 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
siz.set(Sprecision,0,0,8); // Image samples have original bit-depth of 8
siz.set(Ssigned,0,0,false); // Image samples are originally unsigned
- kdu_params *siz_ref = &siz; siz_ref->finalize();
- siz_params transformed_siz; // Use this one to construct code-strea
+ kdu_params *siz_ref = &siz;
+ siz_ref->finalize();
+ siz_params transformed_siz; // Use this one to construct code-stream
transformed_siz.copy_from(&siz,-1,-1,-1,0,transpose,false,false);
- // Construct the `kdu_codestream' object and parse all remaining arguments.
-
+ // Construct the `kdu_codestream' object and parse all remaining arguments
U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents();
- if (max_output_size < 1000)
- {
- max_output_size = 1000;
- }
+ max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);
U8 *output_buffer = new U8[max_output_size];
-
- U32 output_size = max_output_size; // gets modified
- LLKDUMemTarget output(output_buffer, output_size, base.getWidth()*base.getHeight()*base.getComponents());
- if (output_size > max_output_size)
- {
- llerrs << llformat("LLImageJ2C::encode output_size(%d) > max_output_size(%d)",
- output_size,max_output_size) << llendl;
- }
+ U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size
+ LLKDUMemTarget output(output_buffer, output_size, max_output_size);
kdu_codestream codestream;
codestream.create(&transformed_siz,&output);
@@ -558,16 +566,22 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
kdu_long layer_bytes[64];
U32 max_bytes = 0;
- if ((num_components >= 3) && !no_weights)
+ if (num_components >= 3)
{
+ // Note that we always use YCC and not YUV
+ // *TODO: Verify this doesn't screws up reversible textures (like sculpties) as YCC is not reversible but YUV is...
set_default_colour_weights(codestream.access_siz());
}
if (reversible)
{
- // If we're doing reversible, assume we're not using quality layers.
- // Yes, I know this is incorrect!
codestream.access_siz()->parse_string("Creversible=yes");
+ // *TODO: we should use yuv in reversible mode and one level since those images are small.
+ // Don't turn this on now though as both create problems on decoding for the moment
+ //codestream.access_siz()->parse_string("Clevels=1");
+ //codestream.access_siz()->parse_string("Cycc=no");
+ // If we're doing reversible (i.e. lossless compression), assumes we're not using quality layers.
+ // *TODO: this is incorrect and unecessary. Try using the regular layer setting.
codestream.access_siz()->parse_string("Clayers=1");
num_layer_specs = 1;
layer_bytes[0] = 0;
@@ -577,6 +591,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
// Rate is the argument passed into the LLImageJ2C which
// specifies the target compression rate. The default is 8:1.
// Possibly if max_bytes < 500, we should just use the default setting?
+ // *TODO: mRate is actually always 8:1 in the viewer. Test different values. Also force to reversible for small (< 500 bytes) textures.
if (base.mRate != 0.f)
{
max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents());
@@ -617,42 +632,56 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
codestream.access_siz()->parse_string(layer_string.c_str());
}
}
- codestream.access_siz()->finalize_all();
- if (cpu_iterations >= 0)
+
+ // Set up data ordering, markers, etc... if precincts or blocks specified
+ if ((mBlocksSize != -1) || (mPrecinctsSize != -1))
{
- codestream.collect_timing_stats(cpu_iterations);
+ if (mPrecinctsSize != -1)
+ {
+ std::string precincts_string = llformat("Cprecincts={%d,%d}",mPrecinctsSize,mPrecinctsSize);
+ codestream.access_siz()->parse_string(precincts_string.c_str());
+ }
+ if (mBlocksSize != -1)
+ {
+ std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize);
+ codestream.access_siz()->parse_string(blocks_string.c_str());
+ }
+ std::string ordering_string = llformat("Corder=RPCL");
+ codestream.access_siz()->parse_string(ordering_string.c_str());
+ std::string PLT_string = llformat("ORGgen_plt=yes");
+ codestream.access_siz()->parse_string(PLT_string.c_str());
+ std::string Parts_string = llformat("ORGtparts=R");
+ codestream.access_siz()->parse_string(Parts_string.c_str());
}
+
+ codestream.access_siz()->finalize_all();
codestream.change_appearance(transpose,vflip,hflip);
// Now we are ready for sample data processing.
- kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream);
- bool done = false;
- while (!done)
- {
- // Process line by line
- done = true;
- if (tile->advance_components())
- {
- done = false;
- tile->process_components();
- }
- }
+ kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream);
+ bool done = false;
+ while (!done)
+ {
+ // Process line by line
+ if (tile->advance_components())
+ {
+ tile->process_components();
+ }
+ else
+ {
+ done = true;
+ }
+ }
// Produce the compressed output
- codestream.flush(layer_bytes,num_layer_specs);
+ codestream.flush(layer_bytes,num_layer_specs);
// Cleanup
- delete tile;
-
+ delete tile;
codestream.destroy();
- if (record_stream != NULL)
- {
- delete record_stream;
- }
// Now that we're done encoding, create the new data buffer for the compressed
// image and stick it there.
-
base.copyData(output_buffer, output_size);
base.updateData(); // set width, height
delete[] output_buffer;
@@ -674,19 +703,19 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
{
// *FIX: kdu calls our callback function if there's an error, and
- // then bombs. To regain control, we throw an exception, and
+ // then bombs. To regain control, we throw an exception, and
// catch it here.
try
{
setupCodeStream(base, FALSE, MODE_FAST);
return TRUE;
}
- catch( const char* msg )
+ catch (const char* msg)
{
base.setLastError(ll_safe_string(msg));
return FALSE;
}
- catch( ... )
+ catch (...)
{
base.setLastError( "Unknown J2C error" );
return FALSE;
@@ -699,37 +728,49 @@ void set_default_colour_weights(kdu_params *siz)
assert(cod != NULL);
bool can_use_ycc = true;
- bool rev0=false;
- int depth0=0, sub_x0=1, sub_y0=1;
- for (int c=0; c < 3; c++)
+ bool rev0 = false;
+ int depth0 = 0, sub_x0 = 1, sub_y0 = 1;
+ for (int c = 0; c < 3; c++)
{
- int depth=0; siz->get(Sprecision,c,0,depth);
- int sub_y=1; siz->get(Ssampling,c,0,sub_y);
- int sub_x=1; siz->get(Ssampling,c,1,sub_x);
+ int depth = 0; siz->get(Sprecision,c,0,depth);
+ int sub_y = 1; siz->get(Ssampling,c,0,sub_y);
+ int sub_x = 1; siz->get(Ssampling,c,1,sub_x);
kdu_params *coc = cod->access_relation(-1,c);
- bool rev=false; coc->get(Creversible,0,0,rev);
+ bool rev = false; coc->get(Creversible,0,0,rev);
if (c == 0)
- { rev0=rev; depth0=depth; sub_x0=sub_x; sub_y0=sub_y; }
- else if ((rev != rev0) || (depth != depth0) ||
- (sub_x != sub_x0) || (sub_y != sub_y0))
+ {
+ rev0 = rev; depth0 = depth; sub_x0 = sub_x; sub_y0 = sub_y;
+ }
+ else if ((rev != rev0) || (depth != depth0) ||
+ (sub_x != sub_x0) || (sub_y != sub_y0))
+ {
can_use_ycc = false;
+ }
}
if (!can_use_ycc)
+ {
return;
+ }
bool use_ycc;
if (!cod->get(Cycc,0,0,use_ycc))
+ {
cod->set(Cycc,0,0,use_ycc=true);
+ }
if (!use_ycc)
+ {
return;
+ }
float weight;
- if (cod->get(Clev_weights,0,0,weight) ||
- cod->get(Cband_weights,0,0,weight))
- return; // Weights already specified explicitly.
+ if (cod->get(Clev_weights,0,0,weight) || cod->get(Cband_weights,0,0,weight))
+ {
+ // Weights already specified explicitly -> nothing to do
+ return;
+ }
- /* These example weights are adapted from numbers generated by Marcus Nadenau
- at EPFL, for a viewing distance of 15 cm and a display resolution of
- 300 DPI. */
+ // These example weights are adapted from numbers generated by Marcus Nadenau
+ // at EPFL, for a viewing distance of 15 cm and a display resolution of
+ // 300 DPI.
cod->parse_string("Cband_weights:C0="
"{0.0901},{0.2758},{0.2758},"
@@ -775,7 +816,7 @@ all necessary level shifting, type conversion, rounding and truncation. */
val += 128;
if (val & ((-1)<<8))
{
- val = (val<0)?0:255;
+ val = (val < 0 ? 0 : 255);
}
*dest = (kdu_byte) val;
}
@@ -793,7 +834,7 @@ all necessary level shifting, type conversion, rounding and truncation. */
val += 128;
if (val & ((-1)<<8))
{
- val = (val<0)?0:255;
+ val = (val < 0 ? 0 : 255);
}
*dest = (kdu_byte) val;
}
@@ -816,7 +857,7 @@ all necessary level shifting, type conversion, rounding and truncation. */
val += 128;
if (val & ((-1)<<8))
{
- val = (val<0)?0:255;
+ val = (val < 0 ? 0 : 255);
}
*dest = (kdu_byte) val;
}
@@ -835,7 +876,7 @@ all necessary level shifting, type conversion, rounding and truncation. */
val += 128;
if (val & ((-1)<<8))
{
- val = (val<0)?0:(256-(1<<upshift));
+ val = (val < 0 ? 0 : 256 - (1<<upshift));
}
*dest = (kdu_byte) val;
}
@@ -857,7 +898,7 @@ all necessary level shifting, type conversion, rounding and truncation. */
val += 128;
if (val & ((-1)<<8))
{
- val = (val<0)?0:255;
+ val = (val < 0 ? 0 : 255);
}
*dest = (kdu_byte) val;
}
@@ -873,7 +914,7 @@ all necessary level shifting, type conversion, rounding and truncation. */
val += 128;
if (val & ((-1)<<8))
{
- val = (val<0)?0:(256-(1<<upshift));
+ val = (val < 0 ? 0 : 256 - (1<<upshift));
}
*dest = (kdu_byte) val;
}
@@ -892,17 +933,17 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)
mNumComponents = tile.get_num_components();
- llassert(mNumComponents<=4);
+ llassert(mNumComponents <= 4);
mUseYCC = tile.get_ycc();
- for (c=0; c<4; ++c)
+ for (c = 0; c < 4; ++c)
{
mReversible[c] = false;
mBitDepths[c] = 0;
}
// Open tile-components and create processing engines and resources
- for (c=0; c < mNumComponents; c++)
+ for (c = 0; c < mNumComponents; c++)
{
mComps[c] = mTile.access_component(c);
mReversible[c] = mComps[c].get_reversible();
@@ -929,7 +970,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)
}
}
mAllocator.finalize(); // Actually creates buffering resources
- for (c=0; c < mNumComponents; c++)
+ for (c = 0; c < mNumComponents; c++)
{
mLines[c].create(); // Grabs resources from the allocator.
}
@@ -937,13 +978,11 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)
LLKDUDecodeState::~LLKDUDecodeState()
{
- S32 c;
// Cleanup
- for (c=0; c < mNumComponents; c++)
+ for (S32 c = 0; c < mNumComponents; c++)
{
mEngines[c].destroy(); // engines are interfaces; no default destructors
}
-
mTile.close();
}
@@ -962,7 +1001,7 @@ separation between consecutive rows in the real buffer. */
LLTimer decode_timer;
while (mDims.size.y--)
{
- for (c=0; c < mNumComponents; c++)
+ for (c = 0; c < mNumComponents; c++)
{
mEngines[c].pull(mLines[c],true);
}
@@ -970,7 +1009,7 @@ separation between consecutive rows in the real buffer. */
{
kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);
}
- for (c=0; c < mNumComponents; c++)
+ for (c = 0; c < mNumComponents; c++)
{
transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]);
}
@@ -990,96 +1029,100 @@ separation between consecutive rows in the real buffer. */
kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream codestream)
{
- int n;
-
- this->codestream = codestream;
- codestream.get_valid_tiles(valid_tile_indices);
- tile_idx = valid_tile_indices.pos;
- tile = codestream.open_tile(tile_idx,NULL);
-
- // Set up the individual components
- num_components = codestream.get_num_components(true);
- components = new kdc_component_flow_control[num_components];
- count_delta = 0;
- kdc_component_flow_control *comp = components;
- for (n = 0; n < num_components; n++, comp++)
- {
- comp->line = NULL;
- comp->reader = img_in;
- kdu_coords subsampling;
- codestream.get_subsampling(n,subsampling,true);
- kdu_dims dims;
- codestream.get_tile_dims(tile_idx,n,dims,true);
- comp->vert_subsampling = subsampling.y;
- if ((n == 0) || (comp->vert_subsampling < count_delta))
- {
- count_delta = comp->vert_subsampling;
- }
- comp->ratio_counter = 0;
- comp->remaining_lines = comp->initial_lines = dims.size.y;
- }
- assert(num_components >= 0);
-
- tile.set_components_of_interest(num_components);
- max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false);
+ int n;
+
+ this->codestream = codestream;
+ codestream.get_valid_tiles(valid_tile_indices);
+ tile_idx = valid_tile_indices.pos;
+ tile = codestream.open_tile(tile_idx,NULL);
+
+ // Set up the individual components
+ num_components = codestream.get_num_components(true);
+ components = new kdc_component_flow_control[num_components];
+ count_delta = 0;
+ kdc_component_flow_control *comp = components;
+ for (n = 0; n < num_components; n++, comp++)
+ {
+ comp->line = NULL;
+ comp->reader = img_in;
+ kdu_coords subsampling;
+ codestream.get_subsampling(n,subsampling,true);
+ kdu_dims dims;
+ codestream.get_tile_dims(tile_idx,n,dims,true);
+ comp->vert_subsampling = subsampling.y;
+ if ((n == 0) || (comp->vert_subsampling < count_delta))
+ {
+ count_delta = comp->vert_subsampling;
+ }
+ comp->ratio_counter = 0;
+ comp->remaining_lines = comp->initial_lines = dims.size.y;
+ }
+ assert(num_components >= 0);
+
+ tile.set_components_of_interest(num_components);
+ max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false);
}
kdc_flow_control::~kdc_flow_control()
{
- if (components != NULL)
- delete[] components;
- if (engine.exists())
- engine.destroy();
+ if (components != NULL)
+ {
+ delete[] components;
+ }
+ if (engine.exists())
+ {
+ engine.destroy();
+ }
}
bool kdc_flow_control::advance_components()
{
- bool found_line = false;
- while (!found_line)
- {
- bool all_done = true;
- kdc_component_flow_control *comp = components;
- for (int n = 0; n < num_components; n++, comp++)
- {
- assert(comp->ratio_counter >= 0);
- if (comp->remaining_lines > 0)
- {
- all_done = false;
- comp->ratio_counter -= count_delta;
- if (comp->ratio_counter < 0)
- {
- found_line = true;
- comp->line = engine.exchange_line(n,NULL,NULL);
- assert(comp->line != NULL);
+ bool found_line = false;
+ while (!found_line)
+ {
+ bool all_done = true;
+ kdc_component_flow_control *comp = components;
+ for (int n = 0; n < num_components; n++, comp++)
+ {
+ assert(comp->ratio_counter >= 0);
+ if (comp->remaining_lines > 0)
+ {
+ all_done = false;
+ comp->ratio_counter -= count_delta;
+ if (comp->ratio_counter < 0)
+ {
+ found_line = true;
+ comp->line = engine.exchange_line(n,NULL,NULL);
+ assert(comp->line != NULL);
if (comp->line->get_width())
{
comp->reader->get(n,*(comp->line),0);
}
- }
- }
- }
- if (all_done)
- {
- return false;
- }
- }
- return true;
+ }
+ }
+ }
+ if (all_done)
+ {
+ return false;
+ }
+ }
+ return true;
}
void kdc_flow_control::process_components()
{
- kdc_component_flow_control *comp = components;
- for (int n = 0; n < num_components; n++, comp++)
- {
- if (comp->ratio_counter < 0)
- {
- comp->ratio_counter += comp->vert_subsampling;
- assert(comp->ratio_counter >= 0);
- assert(comp->remaining_lines > 0);
- comp->remaining_lines--;
- assert(comp->line != NULL);
- engine.exchange_line(n,comp->line,NULL);
- comp->line = NULL;
- }
- }
+ kdc_component_flow_control *comp = components;
+ for (int n = 0; n < num_components; n++, comp++)
+ {
+ if (comp->ratio_counter < 0)
+ {
+ comp->ratio_counter += comp->vert_subsampling;
+ assert(comp->ratio_counter >= 0);
+ assert(comp->remaining_lines > 0);
+ comp->remaining_lines--;
+ assert(comp->line != NULL);
+ engine.exchange_line(n,comp->line,NULL);
+ comp->line = NULL;
+ }
+ }
}
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index 5628f69eeb..9fce58b762 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -58,17 +58,21 @@ protected:
/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
BOOL reversible=FALSE);
+ /*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
+ /*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);
private:
+ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode);
void cleanupCodeStream();
- BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );
// Encode variable
LLKDUMemSource *mInputp;
kdu_codestream *mCodeStreamp;
kdu_coords *mTPosp; // tile position
kdu_dims *mTileIndicesp;
+ int mBlocksSize;
+ int mPrecinctsSize;
// Temporary variables for in-progress decodes...
LLImageRaw *mRawImagep;
diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp
index 1f549cbbe0..0347475559 100644
--- a/indra/llkdu/llkdumem.cpp
+++ b/indra/llkdu/llkdumem.cpp
@@ -47,12 +47,12 @@ LLKDUMemIn::LLKDUMemIn(const U8 *data,
num_components = in_num_components;
alignment_bytes = 0;
- for (n=0; n<3; ++n)
+ for (n = 0; n < 3; ++n)
{
precision[n] = 0;
}
- for (n=0; n < num_components; ++n)
+ for (n = 0; n < num_components; ++n)
{
siz->set(Sdims,n,0,rows);
siz->set(Sdims,n,1,cols);
@@ -80,12 +80,12 @@ LLKDUMemIn::~LLKDUMemIn()
}
image_line_buf *tmp;
while ((tmp=incomplete_lines) != NULL)
- {
+ {
incomplete_lines = tmp->next;
delete tmp;
}
while ((tmp=free_lines) != NULL)
- {
+ {
free_lines = tmp->next;
delete tmp;
}
@@ -98,16 +98,16 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)
assert((idx >= 0) && (idx < num_components));
x_tnum = x_tnum*num_components+idx;
image_line_buf *scan, *prev=NULL;
- for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next)
- {
+ for (scan = incomplete_lines; scan != NULL; prev = scan, scan = scan->next)
+ {
assert(scan->next_x_tnum >= x_tnum);
if (scan->next_x_tnum == x_tnum)
{
break;
}
- }
+ }
if (scan == NULL)
- { // Need to read a new image line.
+ { // Need to read a new image line.
assert(x_tnum == 0); // Must consume in very specific order.
if (num_unread_rows == 0)
{
@@ -134,7 +134,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)
num_unread_rows--;
scan->accessed_samples = 0;
scan->next_x_tnum = 0;
- }
+ }
assert((cols-scan->accessed_samples) >= line.get_width());
@@ -161,7 +161,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)
}
}
else
- {
+ {
kdu_sample16 *dp = line.get_buf16();
if (line.is_absolute())
{ // 16-bit absolute integers
@@ -177,7 +177,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)
dp->ival = (((kdu_int16)(*sp)) - 128) << (KDU_FIX_POINT-8);
}
}
- }
+ }
scan->next_x_tnum++;
if (idx == (num_components-1))
diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h
index 7064de4408..9d923fc367 100644
--- a/indra/llkdu/llkdumem.h
+++ b/indra/llkdu/llkdumem.h
@@ -39,7 +39,7 @@
class LLKDUMemSource: public kdu_compressed_source
{
-public: // Member functions
+public:
LLKDUMemSource(U8 *input_buffer, U32 size)
{
mData = input_buffer;
@@ -47,11 +47,11 @@ public: // Member functions
mCurPos = 0;
}
- ~LLKDUMemSource()
+ ~LLKDUMemSource()
{
}
- int read(kdu_byte *buf, int num_bytes)
+ int read(kdu_byte *buf, int num_bytes)
{
U32 num_out;
num_out = num_bytes;
@@ -70,7 +70,7 @@ public: // Member functions
mCurPos = 0;
}
-private: // Data
+private:
U8 *mData;
U32 mSize;
U32 mCurPos;
@@ -78,7 +78,7 @@ private: // Data
class LLKDUMemTarget: public kdu_compressed_target
{
-public: // Member functions
+public:
LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size)
{
mData = output_buffer;
@@ -87,11 +87,11 @@ public: // Member functions
mOutputSize = &output_size;
}
- ~LLKDUMemTarget()
- {
+ ~LLKDUMemTarget()
+ {
}
- bool write(const kdu_byte *buf, int num_bytes)
+ bool write(const kdu_byte *buf, int num_bytes)
{
U32 num_out;
num_out = num_bytes;
@@ -108,7 +108,7 @@ public: // Member functions
return true;
}
-private: // Data
+private:
U8 *mData;
U32 mSize;
U32 mCurPos;
@@ -117,27 +117,27 @@ private: // Data
class LLKDUMemIn : public kdu_image_in_base
{
-public: // Member functions
- LLKDUMemIn(const U8 *data,
+public:
+ LLKDUMemIn(const U8 *data,
const U32 size,
const U16 rows,
const U16 cols,
U8 in_num_components,
siz_params *siz);
- ~LLKDUMemIn();
+ ~LLKDUMemIn();
- bool get(int comp_idx, kdu_line_buf &line, int x_tnum);
+ bool get(int comp_idx, kdu_line_buf &line, int x_tnum);
-private: // Data
+private:
const U8 *mData;
- int first_comp_idx;
- int num_components;
- int rows, cols;
- int alignment_bytes; // Number of 0's at end of each line.
- int precision[3];
- image_line_buf *incomplete_lines; // Each "sample" represents a full pixel
- image_line_buf *free_lines;
- int num_unread_rows;
+ int first_comp_idx;
+ int num_components;
+ int rows, cols;
+ int alignment_bytes; // Number of 0's at end of each line.
+ int precision[3];
+ image_line_buf *incomplete_lines; // Each "sample" represents a full pixel
+ image_line_buf *free_lines;
+ int num_unread_rows;
U32 mCurPos;
U32 mDataSize;
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index 7b29d92ea0..c4eec1835c 100644
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -39,56 +39,24 @@
//static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
///////////////////////////////////////////////////////////////////////////////
-// LLLoadingIndicator::Data class
+// LLLoadingIndicator class
///////////////////////////////////////////////////////////////////////////////
-/**
- * Pre-loaded images shared by all instances of the widget
- */
-class LLLoadingIndicator::Data: public LLSingleton<LLLoadingIndicator::Data>
+LLLoadingIndicator::LLLoadingIndicator(const Params& p)
+: LLUICtrl(p),
+ mImagesPerSec(p.images_per_sec > 0 ? p.images_per_sec : 1.0f),
+ mCurImageIdx(0)
{
-public:
- /*virtual*/ void initSingleton(); // from LLSingleton
-
- LLPointer<LLUIImage> getNextImage(S8& idx) const;
- U8 getImagesCount() const { return NIMAGES; }
-private:
-
- static const U8 NIMAGES = 12;
- LLPointer<LLUIImage> mImages[NIMAGES];
-};
+}
-// virtual
-// Called right after the instance gets constructed.
-void LLLoadingIndicator::Data::initSingleton()
+void LLLoadingIndicator::initFromParams(const Params& p)
{
- // Load images.
- for (U8 i = 0; i < NIMAGES; ++i)
+ for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end();
+ it != end_it;
+ ++it)
{
- std::string img_name = llformat("Progress_%d", i+1);
- mImages[i] = LLUI::getUIImage(img_name, 0);
- llassert(mImages[i]);
+ mImages.push_back(it->getValue());
}
-}
-
-LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const
-{
- // Calculate next index, performing array bounds checking.
- idx = (idx >= NIMAGES || idx < 0) ? 0 : (idx + 1) % NIMAGES;
- return mImages[idx];
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// LLLoadingIndicator class
-///////////////////////////////////////////////////////////////////////////////
-
-LLLoadingIndicator::LLLoadingIndicator(const Params& p)
-: LLUICtrl(p)
- , mRotationsPerSec(p.rotations_per_sec > 0 ? p.rotations_per_sec : 1.0f)
- , mCurImageIdx(-1)
-{
- // Select initial image.
- mCurImagep = Data::instance().getNextImage(mCurImageIdx);
// Start timer for switching images.
start();
@@ -100,16 +68,21 @@ void LLLoadingIndicator::draw()
if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired())
{
// Switch to the next image.
- mCurImagep = Data::instance().getNextImage(mCurImageIdx);
+ if (!mImages.empty())
+ {
+ mCurImageIdx = (mCurImageIdx + 1) % mImages.size();
+ }
// Restart timer.
start();
}
+ LLUIImagePtr cur_image = mImages.empty() ? LLUIImagePtr(NULL) : mImages[mCurImageIdx];
+
// Draw current image.
- if( mCurImagep.notNull() )
+ if( cur_image.notNull() )
{
- mCurImagep->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);
+ cur_image->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);
}
LLUICtrl::draw();
@@ -123,6 +96,6 @@ void LLLoadingIndicator::stop()
void LLLoadingIndicator::start()
{
mImageSwitchTimer.start();
- F32 period = 1.0f / (Data::instance().getImagesCount() * mRotationsPerSec);
+ F32 period = 1.0f / (mImages.size() * mImagesPerSec);
mImageSwitchTimer.setTimerExpirySec(period);
}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index 4e4a224ef6..c0cb1cc74a 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -36,8 +36,8 @@
/**
* Perpetual loading indicator (a la MacOSX or YouTube)
*
- * Number of rotations per second can be overriden
- * with the "roations_per_sec" parameter.
+ * Number of rotations per second can be overridden
+ * with the "images_per_sec" parameter.
*
* Can start/stop spinning.
*
@@ -49,11 +49,24 @@ class LLLoadingIndicator
{
LOG_CLASS(LLLoadingIndicator);
public:
+
+ struct Images : public LLInitParam::Block<Images>
+ {
+ Multiple<LLUIImage*> image;
+
+ Images()
+ : image("image")
+ {}
+ };
+
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
- Optional<F32> rotations_per_sec;
+ Optional<F32> images_per_sec;
+ Batch<Images> images;
+
Params()
- : rotations_per_sec("rotations_per_sec", 1.0f)
+ : images_per_sec("images_per_sec", 1.0f),
+ images("images")
{}
};
@@ -74,14 +87,15 @@ public:
private:
LLLoadingIndicator(const Params&);
- friend class LLUICtrlFactory;
+ void initFromParams(const Params&);
- class Data;
+ friend class LLUICtrlFactory;
- F32 mRotationsPerSec;
+ F32 mImagesPerSec;
S8 mCurImageIdx;
- LLPointer<LLUIImage> mCurImagep;
LLFrameTimer mImageSwitchTimer;
+
+ std::vector<LLUIImagePtr> mImages;
};
#endif // LL_LLLOADINGINDICATOR_H
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 87669574c2..8020ca802b 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1626,8 +1626,8 @@ void LLUI::cleanupClass()
{
if(sImageProvider)
{
- sImageProvider->cleanUp();
- }
+ sImageProvider->cleanUp();
+}
}
void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups)
@@ -2074,32 +2074,32 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
namespace LLInitParam
{
- TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, name, value, func, min_count, max_count),
+ ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ : super_t(color),
red("red"),
green("green"),
blue("blue"),
alpha("alpha"),
control("")
{
- setBlockFromValue();
+ updateBlockFromValue();
}
- void TypedParam<LLUIColor>::setValueFromBlock() const
+ void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
{
if (control.isProvided())
{
- mData.mValue = LLUIColorTable::instance().getColor(control);
+ updateValue(LLUIColorTable::instance().getColor(control));
}
else
{
- mData.mValue = LLColor4(red, green, blue, alpha);
+ updateValue(LLColor4(red, green, blue, alpha));
}
}
- void TypedParam<LLUIColor>::setBlockFromValue()
+ void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
{
- LLColor4 color = mData.mValue.get();
+ LLColor4 color = getValue();
red.set(color.mV[VRED], false);
green.set(color.mV[VGREEN], false);
blue.set(color.mV[VBLUE], false);
@@ -2107,38 +2107,32 @@ namespace LLInitParam
control.set("", false);
}
- void TypeValues<LLUIColor>::declareValues()
- {
- declare("white", LLColor4::white);
- declare("black", LLColor4::black);
- declare("red", LLColor4::red);
- declare("green", LLColor4::green);
- declare("blue", LLColor4::blue);
- }
-
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
{
return !(a->getFontDesc() < b->getFontDesc())
&& !(b->getFontDesc() < a->getFontDesc());
}
- TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, _name, value, func, min_count, max_count),
+ ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ : super_t(fontp),
name("name"),
size("size"),
style("style")
{
- setBlockFromValue();
+ if (!fontp)
+ {
+ updateValue(LLFontGL::getFontDefault());
+ }
addSynonym(name, "");
- setBlockFromValue();
+ updateBlockFromValue();
}
- void TypedParam<const LLFontGL*>::setValueFromBlock() const
+ void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
{
const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
if (res_fontp)
{
- mData.mValue = res_fontp;
+ updateValue(res_fontp);
return;
}
@@ -2148,22 +2142,26 @@ namespace LLInitParam
const LLFontGL* fontp = LLFontGL::getFont(desc);
if (fontp)
{
- mData.mValue = fontp;
- }
+ updateValue(fontp);
+ }
+ else
+ {
+ updateValue(LLFontGL::getFontDefault());
+ }
}
- void TypedParam<const LLFontGL*>::setBlockFromValue()
+ void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
{
- if (mData.mValue)
+ if (getValue())
{
- name.set(LLFontGL::nameFromFont(mData.mValue), false);
- size.set(LLFontGL::sizeFromFont(mData.mValue), false);
- style.set(LLFontGL::getStringFromStyle(mData.mValue->getFontDesc().getStyle()), false);
+ name.set(LLFontGL::nameFromFont(getValue()), false);
+ size.set(LLFontGL::sizeFromFont(getValue()), false);
+ style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), false);
}
}
- TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, name, value, func, min_count, max_count),
+ ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect)
+ : super_t(rect),
left("left"),
top("top"),
right("right"),
@@ -2171,10 +2169,10 @@ namespace LLInitParam
width("width"),
height("height")
{
- setBlockFromValue();
+ updateBlockFromValue();
}
- void TypedParam<LLRect>::setValueFromBlock() const
+ void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
{
LLRect rect;
@@ -2235,40 +2233,41 @@ namespace LLInitParam
rect.mBottom = bottom;
rect.mTop = top;
}
- mData.mValue = rect;
+ updateValue(rect);
}
- void TypedParam<LLRect>::setBlockFromValue()
+ void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue()
{
// because of the ambiguity in specifying a rect by position and/or dimensions
// we clear the "provided" flag so that values from xui/etc have priority
// over those calculated from the rect object
- left.set(mData.mValue.mLeft, false);
- right.set(mData.mValue.mRight, false);
- bottom.set(mData.mValue.mBottom, false);
- top.set(mData.mValue.mTop, false);
- width.set(mData.mValue.getWidth(), false);
- height.set(mData.mValue.getHeight(), false);
+ LLRect& value = getValue();
+ left.set(value.mLeft, false);
+ right.set(value.mRight, false);
+ bottom.set(value.mBottom, false);
+ top.set(value.mTop, false);
+ width.set(value.getWidth(), false);
+ height.set(value.getHeight(), false);
}
- TypedParam<LLCoordGL>::TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, name, value, func, min_count, max_count),
+ ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
+ : super_t(coord),
x("x"),
y("y")
{
- setBlockFromValue();
+ updateBlockFromValue();
}
- void TypedParam<LLCoordGL>::setValueFromBlock() const
+ void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
{
- mData.mValue.set(x, y);
+ updateValue(LLCoordGL(x, y));
}
- void TypedParam<LLCoordGL>::setBlockFromValue()
+ void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue()
{
- x.set(mData.mValue.mX, false);
- y.set(mData.mValue.mY, false);
+ x.set(getValue().mX, false);
+ y.set(getValue().mY, false);
}
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 50cb9e6632..6a43477693 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -398,10 +398,10 @@ public:
namespace LLInitParam
{
template<>
- class TypedParam<LLRect>
- : public BlockValue<LLRect>
+ class ParamValue<LLRect, TypeValues<LLRect> >
+ : public CustomParamValue<LLRect>
{
- typedef BlockValue<LLRect> super_t;
+ typedef CustomParamValue<LLRect> super_t;
public:
Optional<S32> left,
top,
@@ -410,62 +410,43 @@ namespace LLInitParam
width,
height;
- TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
+ ParamValue(const LLRect& value);
- void setValueFromBlock() const;
- void setBlockFromValue();
+ void updateValueFromBlock();
+ void updateBlockFromValue();
};
template<>
- struct TypeValues<LLUIColor> : public TypeValuesHelper<LLUIColor>
+ class ParamValue<LLUIColor, TypeValues<LLUIColor> >
+ : public CustomParamValue<LLUIColor>
{
- static void declareValues();
- };
+ typedef CustomParamValue<LLUIColor> super_t;
- template<>
- class TypedParam<LLUIColor>
- : public BlockValue<LLUIColor>
- {
- typedef BlockValue<LLUIColor> super_t;
public:
- Optional<F32> red,
- green,
- blue,
- alpha;
- Optional<std::string> control;
-
- TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
- void setValueFromBlock() const;
- void setBlockFromValue();
+ Optional<F32> red,
+ green,
+ blue,
+ alpha;
+ Optional<std::string> control;
+
+ ParamValue(const LLUIColor& color);
+ void updateValueFromBlock();
+ void updateBlockFromValue();
};
- // provide a better default for Optional<const LLFontGL*> than NULL
- template <>
- struct DefaultInitializer<const LLFontGL*>
- {
- // return reference to a single default instance of T
- // built-in types will be initialized to zero, default constructor otherwise
- static const LLFontGL* get()
- {
- static const LLFontGL* sDefaultFont = LLFontGL::getFontDefault();
- return sDefaultFont;
- }
- };
-
-
template<>
- class TypedParam<const LLFontGL*>
- : public BlockValue<const LLFontGL*>
+ class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >
+ : public CustomParamValue<const LLFontGL* >
{
- typedef BlockValue<const LLFontGL*> super_t;
+ typedef CustomParamValue<const LLFontGL*> super_t;
public:
Optional<std::string> name,
size,
style;
- TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
- void setValueFromBlock() const;
- void setBlockFromValue();
+ ParamValue(const LLFontGL* value);
+ void updateValueFromBlock();
+ void updateBlockFromValue();
};
template<>
@@ -494,17 +475,17 @@ namespace LLInitParam
template<>
- class TypedParam<LLCoordGL>
- : public BlockValue<LLCoordGL>
+ class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
+ : public CustomParamValue<LLCoordGL>
{
- typedef BlockValue<LLCoordGL> super_t;
+ typedef CustomParamValue<LLCoordGL> super_t;
public:
Optional<S32> x,
y;
- TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count);
- void setValueFromBlock() const;
- void setBlockFromValue();
+ ParamValue(const LLCoordGL& val);
+ void updateValueFromBlock();
+ void updateBlockFromValue();
};
}
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index 1ffad4806e..f37947a50b 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -155,32 +155,32 @@ void LLUIImage::onImageLoaded()
namespace LLInitParam
{
- void TypedParam<LLUIImage*>::setValueFromBlock() const
+ void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
{
// The keyword "none" is specifically requesting a null image
// do not default to current value. Used to overwrite template images.
if (name() == "none")
{
- mData.mValue = NULL;
+ updateValue(NULL);
return;
}
LLUIImage* imagep = LLUI::getUIImage(name());
if (imagep)
{
- mData.mValue = imagep;
+ updateValue(imagep);
}
}
- void TypedParam<LLUIImage*>::setBlockFromValue()
+ void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
{
- if (mData.mValue == NULL)
+ if (getValue() == NULL)
{
name.set("none", false);
}
else
{
- name.set(mData.mValue->getName(), false);
+ name.set(getValue()->getName(), false);
}
}
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
index 38107c112d..139d88e0ac 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llui/lluiimage.h
@@ -92,22 +92,23 @@ protected:
namespace LLInitParam
{
template<>
- class TypedParam<LLUIImage*, TypeValues<LLUIImage*>, false>
- : public BlockValue<LLUIImage*>
+ class ParamValue<LLUIImage*, TypeValues<LLUIImage*> >
+ : public CustomParamValue<LLUIImage*>
{
typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
- typedef BlockValue<LLUIImage*> super_t;
+ typedef CustomParamValue<LLUIImage*> super_t;
public:
Optional<std::string> name;
- TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, name, value, func, min_count, max_count)
+ ParamValue(LLUIImage* const& image)
+ : super_t(image)
{
- setBlockFromValue();
+ updateBlockFromValue();
+ addSynonym(name, "name");
}
- void setValueFromBlock() const;
- void setBlockFromValue();
+ void updateValueFromBlock();
+ void updateBlockFromValue();
};
// Need custom comparison function for our test app, which only loads
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index ac2412c928..75946b2416 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -114,32 +114,30 @@ namespace LLInitParam
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
}
- void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {}
+ void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {}
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){}
+ void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
+ void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
descriptor.mCurrentBlockPtr = this;
}
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }
- bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; }
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; }
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }
+ void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {}
+ bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }
bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
- TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, name, value, func, min_count, max_count)
+ ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ : super_t(color)
{}
- void TypedParam<LLUIColor>::setValueFromBlock() const
+ void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
{}
- void TypedParam<LLUIColor>::setBlockFromValue()
- {}
-
- void TypeValues<LLUIColor>::declareValues()
+ void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -147,14 +145,14 @@ namespace LLInitParam
return false;
}
- TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, _name, value, func, min_count, max_count)
+ ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ : super_t(fontp)
{}
- void TypedParam<const LLFontGL*>::setValueFromBlock() const
+ void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
{}
- void TypedParam<const LLFontGL*>::setBlockFromValue()
+ void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -166,10 +164,10 @@ namespace LLInitParam
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
- void TypedParam<LLUIImage*>::setValueFromBlock() const
+ void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
{}
- void TypedParam<LLUIImage*>::setBlockFromValue()
+ void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
{}
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 8f0a48018f..2f814f4200 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -70,6 +70,22 @@ S32 LLUIImage::getHeight() const
return 0;
}
+namespace LLInitParam
+{
+ S32 Parser::sNextParseGeneration = 0;
+ BlockDescriptor::BlockDescriptor() {}
+ ParamDescriptor::ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count){}
+ ParamDescriptor::~ParamDescriptor() {}
+
+}
+
namespace tut
{
struct LLUrlEntryData
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index fdaab00f18..aea605c9f2 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -66,11 +66,25 @@ namespace LLInitParam
BaseBlock::BaseBlock() {}
BaseBlock::~BaseBlock() {}
- void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {}
-
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){}
+ S32 Parser::sNextParseGeneration = 0;
+
+ BlockDescriptor::BlockDescriptor() {}
+ ParamDescriptor::ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count){}
+ ParamDescriptor::~ParamDescriptor() {}
+
+ void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {}
+
+ void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
-
+ void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
+
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
descriptor.mCurrentBlockPtr = this;
@@ -84,23 +98,20 @@ namespace LLInitParam
mEnclosingBlockOffset = (U16)(my_addr - block_addr);
}
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; }
- bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; }
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; }
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }
+ void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {}
+ bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }
bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
- TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, name, value, func, min_count, max_count)
+ ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+ : super_t(color)
{}
- void TypedParam<LLUIColor>::setValueFromBlock() const
+ void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
{}
- void TypedParam<LLUIColor>::setBlockFromValue()
- {}
-
- void TypeValues<LLUIColor>::declareValues()
+ void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()
{}
bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -108,14 +119,15 @@ namespace LLInitParam
return false;
}
- TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count)
- : super_t(descriptor, _name, value, func, min_count, max_count)
+
+ ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+ : super_t(fontp)
{}
- void TypedParam<const LLFontGL*>::setValueFromBlock() const
+ void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
{}
- void TypedParam<const LLFontGL*>::setBlockFromValue()
+ void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()
{}
void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -127,10 +139,10 @@ namespace LLInitParam
void TypeValues<LLFontGL::ShadowType>::declareValues()
{}
- void TypedParam<LLUIImage*>::setValueFromBlock() const
+ void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
{}
- void TypedParam<LLUIImage*>::setBlockFromValue()
+ void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()
{}
bool ParamCompare<LLUIImage*, false>::equals(
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index fcdbaa4309..3c4eb70a5d 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -44,8 +44,51 @@ namespace LLInitParam
}
//
+ // ParamDescriptor
+ //
+ ParamDescriptor::ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count)
+ : mParamHandle(p),
+ mMergeFunc(merge_func),
+ mDeserializeFunc(deserialize_func),
+ mSerializeFunc(serialize_func),
+ mValidationFunc(validation_func),
+ mInspectFunc(inspect_func),
+ mMinCount(min_count),
+ mMaxCount(max_count),
+ mGeneration(0),
+ mUserData(NULL)
+ {}
+
+ ParamDescriptor::ParamDescriptor()
+ : mParamHandle(0),
+ mMergeFunc(NULL),
+ mDeserializeFunc(NULL),
+ mSerializeFunc(NULL),
+ mValidationFunc(NULL),
+ mInspectFunc(NULL),
+ mMinCount(0),
+ mMaxCount(0),
+ mGeneration(0),
+ mUserData(NULL)
+ {}
+
+ ParamDescriptor::~ParamDescriptor()
+ {
+ delete mUserData;
+ }
+
+ //
// Parser
//
+ S32 Parser::sNextParseGeneration = 0;
+
Parser::~Parser()
{}
@@ -73,6 +116,12 @@ namespace LLInitParam
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
}
+ BlockDescriptor::BlockDescriptor()
+ : mMaxParamOffset(0),
+ mInitializationState(UNINITIALIZED),
+ mCurrentBlockPtr(NULL)
+ {}
+
//
// BaseBlock
//
@@ -115,7 +164,7 @@ namespace LLInitParam
bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)
{
- if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end())))
+ if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1))
{
if (!silent)
{
@@ -145,7 +194,7 @@ namespace LLInitParam
return true;
}
- bool 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 LLInitParam::BaseBlock* diff_block) const
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
@@ -212,11 +261,9 @@ namespace LLInitParam
name_stack.pop_back();
}
}
-
- return true;
}
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const
+ bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
@@ -273,11 +320,13 @@ namespace LLInitParam
return true;
}
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation)
{
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
bool names_left = name_stack.first != name_stack.second;
+ S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second;
+
if (names_left)
{
const std::string& top_name = name_stack.first->first;
@@ -294,7 +343,7 @@ namespace LLInitParam
Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
++new_name_stack.first;
- return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second);
+ return deserialize_func(*paramp, p, new_name_stack, parse_generation);
}
}
@@ -306,7 +355,7 @@ namespace LLInitParam
Param* paramp = getParamFromHandle((*it)->mParamHandle);
ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
- if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second))
+ if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))
{
return true;
}
@@ -324,32 +373,32 @@ namespace LLInitParam
}
//static
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name)
+ void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
{
// create a copy of the paramdescriptor in allparams
// so other data structures can store a pointer to it
block_data.mAllParams.push_back(in_param);
- ParamDescriptor& param(block_data.mAllParams.back());
+ ParamDescriptorPtr param(block_data.mAllParams.back());
std::string name(char_name);
- if ((size_t)param.mParamHandle > block_data.mMaxParamOffset)
+ if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
{
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
}
if (name.empty())
{
- block_data.mUnnamedParams.push_back(&param);
+ block_data.mUnnamedParams.push_back(param);
}
else
{
// don't use insert, since we want to overwrite existing entries
- block_data.mNamedParams[name] = &param;
+ block_data.mNamedParams[name] = param;
}
- if (param.mValidationFunc)
+ if (param->mValidationFunc)
{
- block_data.mValidationList.push_back(std::make_pair(param.mParamHandle, param.mValidationFunc));
+ block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
}
}
@@ -367,7 +416,7 @@ namespace LLInitParam
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
}
- ParamDescriptor* param_descriptor = findParamDescriptor(handle);
+ ParamDescriptorPtr param_descriptor = findParamDescriptor(param);
if (param_descriptor)
{
if (synonym.empty())
@@ -382,7 +431,7 @@ namespace LLInitParam
}
}
- void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided)
+ void BaseBlock::paramChanged(const Param& changed_param, bool user_provided)
{
if (user_provided)
{
@@ -404,17 +453,18 @@ namespace LLInitParam
return LLStringUtil::null;
}
- ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
+ ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)
{
+ param_handle_t handle = getHandleFromParam(&param);
BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
it != end_it;
++it)
{
- if (it->mParamHandle == handle) return &(*it);
+ if ((*it)->mParamHandle == handle) return *it;
}
- return NULL;
+ return ParamDescriptorPtr();
}
// take all provided params from other and apply to self
@@ -427,19 +477,14 @@ namespace LLInitParam
it != end_it;
++it)
{
- const Param* other_paramp = other.getParamFromHandle(it->mParamHandle);
- ParamDescriptor::merge_func_t merge_func = it->mMergeFunc;
+ const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle);
+ ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;
if (merge_func)
{
- Param* paramp = getParamFromHandle(it->mParamHandle);
+ Param* paramp = getParamFromHandle((*it)->mParamHandle);
some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
}
}
return some_param_changed;
}
-
- bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b)
- {
- return false;
- }
}
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 1f9045754a..858f8405b4 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -1,5 +1,5 @@
/**
-f * @file llinitparam.h
+ * @file llinitparam.h
* @brief parameter block abstraction for creating complex objects and
* parsing construction parameters from xml and LLSD
*
@@ -29,18 +29,14 @@ f * @file llinitparam.h
#define LL_LLPARAM_H
#include <vector>
-
-#include <stddef.h>
#include <boost/function.hpp>
-#include <boost/bind.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/unordered_map.hpp>
-#include "llregistry.h"
-#include "llmemory.h"
-
+#include <boost/shared_ptr.hpp>
namespace LLInitParam
{
+ template<typename T> const T& defaultValue() { static T value; return value; }
template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
struct ParamCompare
@@ -61,122 +57,119 @@ namespace LLInitParam
}
};
- // default constructor adaptor for InitParam Values
- // constructs default instances of the given type, returned by const reference
- template <typename T>
- struct DefaultInitializer
+ template<>
+ struct ParamCompare<LLSD, false>
{
- typedef const T& T_const_ref;
- // return reference to a single default instance of T
- // built-in types will be initialized to zero, default constructor otherwise
- static T_const_ref get() { static T t = T(); return t; }
+ static bool equals(const LLSD &a, const LLSD &b) { return false; }
};
// helper functions and classes
typedef ptrdiff_t param_handle_t;
+ // empty default implementation of key cache
+ // leverages empty base class optimization
template <typename T>
class TypeValues
{
public:
- // empty default implemenation of key cache
- class KeyCache
+ typedef std::map<std::string, T> value_name_map_t;
+
+ void setValueName(const std::string& key) {}
+ std::string getValueName() const { return ""; }
+ void clearValueName() const {}
+
+ static bool getValueFromName(const std::string& name, T& value)
{
- public:
- void setKey(const std::string& key) {}
- std::string getKey() const { return ""; }
- void clearKey(){}
- };
+ return false;
+ }
- static bool get(const std::string& name, T& value)
+ static bool valueNamesExist()
{
return false;
}
- static bool empty()
+ static std::vector<std::string>* getPossibleValues()
{
- return true;
+ return NULL;
}
- static std::vector<std::string>* getPossibleValues() { return NULL; }
+ static value_name_map_t* getValueNames() {return NULL;}
};
template <typename T, typename DERIVED_TYPE = TypeValues<T> >
class TypeValuesHelper
- : public LLRegistrySingleton<std::string, T, DERIVED_TYPE >
{
- typedef LLRegistrySingleton<std::string, T, DERIVED_TYPE> super_t;
- typedef LLSingleton<DERIVED_TYPE> singleton_t;
public:
+ typedef typename std::map<std::string, T> value_name_map_t;
//TODO: cache key by index to save on param block size
- class KeyCache
+ void setValueName(const std::string& value_name)
{
- public:
- void setKey(const std::string& key)
- {
- mKey = key;
- }
-
- void clearKey()
- {
- mKey = "";
- }
+ mValueName = value_name;
+ }
- std::string getKey() const
- {
- return mKey;
- }
+ std::string getValueName() const
+ {
+ return mValueName;
+ }
- private:
- std::string mKey;
- };
+ void clearValueName() const
+ {
+ mValueName.clear();
+ }
- static bool get(const std::string& name, T& value)
+ static bool getValueFromName(const std::string& name, T& value)
{
- if (!singleton_t::instance().exists(name)) return false;
+ value_name_map_t* map = getValueNames();
+ typename value_name_map_t::iterator found_it = map->find(name);
+ if (found_it == map->end()) return false;
- value = *singleton_t::instance().getValue(name);
+ value = found_it->second;
return true;
}
- static bool empty()
+ static bool valueNamesExist()
{
- return singleton_t::instance().LLRegistry<std::string, T>::empty();
+ return !getValueNames()->empty();
}
- //override this to add name value pairs
- static void declareValues() {}
-
- void initSingleton()
+ static value_name_map_t* getValueNames()
{
- DERIVED_TYPE::declareValues();
- }
+ static value_name_map_t sMap;
+ static bool sInitialized = false;
- static const std::vector<std::string>* getPossibleValues()
- {
- // in order to return a pointer to a member, we lazily
- // evaluate the result and store it in mValues here
- if (singleton_t::instance().mValues.empty())
+ if (!sInitialized)
{
- typename super_t::Registrar::registry_map_t::const_iterator it;
- for (it = super_t::defaultRegistrar().beginItems(); it != super_t::defaultRegistrar().endItems(); ++it)
- {
- singleton_t::instance().mValues.push_back(it->first);
- }
+ sInitialized = true;
+ DERIVED_TYPE::declareValues();
}
- return &singleton_t::instance().mValues;
+ return &sMap;
}
+ static std::vector<std::string>* getPossibleValues()
+ {
+ static std::vector<std::string> sValues;
+
+ value_name_map_t* map = getValueNames();
+ for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
+ it != end_it;
+ ++it)
+ {
+ sValues.push_back(it->first);
+ }
+ return &sValues;
+ }
- protected:
static void declare(const std::string& name, const T& value)
{
- super_t::defaultRegistrar().add(name, value);
+ (*getValueNames())[name] = value;
}
- private:
- std::vector<std::string> mValues;
+ protected:
+ static void getName(const std::string& name, const T& value)
+ {}
+
+ mutable std::string mValueName;
};
class Parser
@@ -193,9 +186,9 @@ namespace LLInitParam
}
};
- typedef std::vector<std::pair<std::string, S32> > name_stack_t;
+ typedef std::vector<std::pair<std::string, S32> > name_stack_t;
typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t;
- typedef std::vector<std::string> possible_values_t;
+ typedef std::vector<std::string> possible_values_t;
typedef bool (*parser_read_func_t)(Parser& parser, void* output);
typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&);
@@ -207,7 +200,7 @@ namespace LLInitParam
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
: mParseSilently(false),
- mParseGeneration(0),
+ mParseGeneration(sNextParseGeneration),
mParserReadFuncs(&read_map),
mParserWriteFuncs(&write_map),
mParserInspectFuncs(&inspect_map)
@@ -252,7 +245,7 @@ namespace LLInitParam
void setParseSilently(bool silent) { mParseSilently = silent; }
S32 getParseGeneration() { return mParseGeneration; }
- S32 newParseGeneration() { return ++mParseGeneration; }
+ S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; }
protected:
@@ -276,6 +269,8 @@ namespace LLInitParam
parser_write_func_map_t* mParserWriteFuncs;
parser_inspect_func_map_t* mParserInspectFuncs;
S32 mParseGeneration;
+
+ static S32 sNextParseGeneration;
};
// used to indicate no matching value to a given name when parsing
@@ -295,12 +290,13 @@ namespace LLInitParam
Param(class BaseBlock* enclosing_block);
// store pointer to enclosing block as offset to reduce space and allow for quick copying
- BaseBlock& enclosingBlock() const
+ class BaseBlock& enclosingBlock() const
{
const U8* my_addr = reinterpret_cast<const U8*>(this);
// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
- return *const_cast<BaseBlock*>(
- reinterpret_cast<const BaseBlock*>(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
+ return *const_cast<class BaseBlock*>
+ (reinterpret_cast<const class BaseBlock*>
+ (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
}
private:
@@ -313,7 +309,11 @@ namespace LLInitParam
// various callbacks and constraints associated with an individual param
struct ParamDescriptor
{
- public:
+ struct UserData
+ {
+ virtual ~UserData() {}
+ };
+
typedef bool(*merge_func_t)(Param&, const Param&, bool);
typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);
typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
@@ -321,40 +321,18 @@ namespace LLInitParam
typedef bool(*validation_func_t)(const Param*);
ParamDescriptor(param_handle_t p,
- merge_func_t merge_func,
- deserialize_func_t deserialize_func,
- serialize_func_t serialize_func,
- validation_func_t validation_func,
- inspect_func_t inspect_func,
- S32 min_count,
- S32 max_count)
- : mParamHandle(p),
- mMergeFunc(merge_func),
- mDeserializeFunc(deserialize_func),
- mSerializeFunc(serialize_func),
- mValidationFunc(validation_func),
- mInspectFunc(inspect_func),
- mMinCount(min_count),
- mMaxCount(max_count),
- mGeneration(0),
- mNumRefs(0)
- {}
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count);
- ParamDescriptor()
- : mParamHandle(0),
- mMergeFunc(NULL),
- mDeserializeFunc(NULL),
- mSerializeFunc(NULL),
- mValidationFunc(NULL),
- mInspectFunc(NULL),
- mMinCount(0),
- mMaxCount(0),
- mGeneration(0),
- mNumRefs(0)
- {}
+ ParamDescriptor();
+ ~ParamDescriptor();
param_handle_t mParamHandle;
-
merge_func_t mMergeFunc;
deserialize_func_t mDeserializeFunc;
serialize_func_t mSerializeFunc;
@@ -364,17 +342,16 @@ namespace LLInitParam
S32 mMaxCount;
S32 mGeneration;
S32 mNumRefs;
+ UserData* mUserData;
};
+ typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
+
// each derived Block class keeps a static data structure maintaining offsets to various params
class BlockDescriptor
{
public:
- BlockDescriptor()
- : mMaxParamOffset(0),
- mInitializationState(UNINITIALIZED),
- mCurrentBlockPtr(NULL)
- {}
+ BlockDescriptor();
typedef enum e_initialization_state
{
@@ -385,12 +362,10 @@ namespace LLInitParam
void aggregateBlockData(BlockDescriptor& src_block_data);
- public:
- typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
- typedef std::vector<ParamDescriptor*> param_list_t;
-
- typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
- typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
+ typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
+ typedef std::vector<ParamDescriptorPtr> param_list_t;
+ typedef std::list<ParamDescriptorPtr> all_params_list_t;
+ typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
param_map_t mNamedParams; // parameters with associated names
param_list_t mUnnamedParams; // parameters with_out_ associated names
@@ -456,6 +431,7 @@ namespace LLInitParam
Param* getParamFromHandle(const param_handle_t param_handle)
{
if (param_handle == 0) return NULL;
+
U8* baseblock_address = reinterpret_cast<U8*>(this);
return reinterpret_cast<Param*>(baseblock_address + param_handle);
}
@@ -469,14 +445,13 @@ namespace LLInitParam
void addSynonym(Param& param, const std::string& synonym);
// Blocks can override this to do custom tracking of changes
- virtual void setLastChangedParam(const Param& last_param, bool user_provided);
+ virtual void paramChanged(const Param& changed_param, bool user_provided);
S32 getLastChangeVersion() const { return mChangeVersion; }
- bool isDefault() const { return mChangeVersion == 0; }
- bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack);
- bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
- bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation);
+ void serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_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(); }
virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
@@ -493,7 +468,10 @@ namespace LLInitParam
return false;
}
- static void addParam(BlockDescriptor& block_data, const ParamDescriptor& param, const char* name);
+ static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
+
+ ParamDescriptorPtr findParamDescriptor(const Param& param);
+
protected:
void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
@@ -512,63 +490,133 @@ namespace LLInitParam
private:
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
- ParamDescriptor* findParamDescriptor(param_handle_t handle);
- };
-
-
- template<typename T>
- struct ParamIterator
- {
- typedef typename std::vector<T>::const_iterator const_iterator;
- typedef typename std::vector<T>::iterator iterator;
};
// these templates allow us to distinguish between template parameters
// that derive from BaseBlock and those that don't
- // this is supposedly faster than boost::is_convertible and its ilk
template<typename T, typename Void = void>
- struct IsBaseBlock
+ struct IsBlock
{
static const bool value = false;
};
template<typename T>
- struct IsBaseBlock<T, typename T::baseblock_base_class_t>
+ struct IsBlock<T, typename T::baseblock_base_class_t>
{
static const bool value = true;
};
+ template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
+ class ParamValue : public NAME_VALUE_LOOKUP
+ {
+ public:
+ typedef const T& value_assignment_t;
+
+ ParamValue(): mValue() {}
+ ParamValue(const T& other) : mValue(other) {}
+
+ void setValue(value_assignment_t val)
+ {
+ mValue = val;
+ }
+
+ value_assignment_t getValue() const
+ {
+ return mValue;
+ }
+
+ T& getValue()
+ {
+ return mValue;
+ }
+
+ private:
+ T mValue;
+ };
+
+ template<typename T, typename NAME_VALUE_LOOKUP>
+ class ParamValue<T, NAME_VALUE_LOOKUP, true>
+ : public T,
+ public NAME_VALUE_LOOKUP
+ {
+ public:
+ typedef const T& value_assignment_t;
+
+ S32 mKeyVersion;
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
+
+ ParamValue()
+ : T(),
+ mKeyVersion(0),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {}
+
+ ParamValue(const T& other)
+ : T(other),
+ mKeyVersion(0),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {
+ }
+
+ void setValue(value_assignment_t val)
+ {
+ *this = val;
+ }
+
+ value_assignment_t getValue() const
+ {
+ return *this;
+ }
+
+ T& getValue()
+ {
+ return *this;
+ }
+ };
+
+ template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ struct ParamIterator
+ {
+ typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator const_iterator;
+ typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator iterator;
+ };
+
// specialize for custom parsing/decomposition of specific classes
// e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
template<typename T,
typename NAME_VALUE_LOOKUP = TypeValues<T>,
bool HAS_MULTIPLE_VALUES = false,
- bool VALUE_IS_BLOCK = IsBaseBlock<T>::value>
+ bool VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
class TypedParam
- : public Param
+ : public Param,
+ public ParamValue<T, NAME_VALUE_LOOKUP>
{
public:
- typedef const T& value_const_ref_t;
- typedef value_const_ref_t value_assignment_t;
- typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+ typedef const T& value_assignment_t;
typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
+ typedef NAME_VALUE_LOOKUP name_value_lookup_t;
+ typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_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)
{
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
&deserializeParam,
&serializeParam,
validate_func,
&inspectParam,
- min_count, max_count);
+ min_count, max_count));
BaseBlock::addParam(block_descriptor, param_descriptor, name);
}
- mData.mValue = value;
+ setValue(value);
}
bool isProvided() const { return Param::anyProvided(); }
@@ -579,27 +627,27 @@ namespace LLInitParam
// no further names in stack, attempt to parse value now
if (name_stack.first == name_stack.second)
{
- if (parser.readValue(typed_param.mData.mValue))
+ if (parser.readValue(typed_param.getValue()))
{
- typed_param.mData.clearKey();
+ typed_param.clearValueName();
typed_param.setProvided(true);
- typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.enclosingBlock().paramChanged(param, true);
return true;
}
// try to parse a known named value
- if(!NAME_VALUE_LOOKUP::empty())
+ if(name_value_lookup_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue))
+ if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
{
- typed_param.mData.setKey(name);
+ typed_param.setValueName(name);
typed_param.setProvided(true);
- typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.enclosingBlock().paramChanged(param, true);
return true;
}
@@ -619,13 +667,13 @@ namespace LLInitParam
name_stack.back().second = parser.newParseGeneration();
}
- std::string key = typed_param.mData.getKey();
+ std::string key = typed_param.getValueName();
// first try to write out name of name/value pair
if (!key.empty())
{
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
+ if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
{
if (!parser.writeValue(key, name_stack))
{
@@ -634,8 +682,9 @@ namespace LLInitParam
}
}
// then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get())) {
- if (!parser.writeValue(typed_param.mData.mValue, name_stack))
+ else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
+ {
+ if (!parser.writeValue(typed_param.getValue(), name_stack))
{
return;
}
@@ -647,18 +696,18 @@ namespace LLInitParam
// tell parser about our actual type
parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
- if (NAME_VALUE_LOOKUP::getPossibleValues())
+ if (name_value_lookup_t::getPossibleValues())
{
- parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
}
}
void set(value_assignment_t val, bool flag_as_provided = true)
{
- mData.mValue = val;
- mData.clearKey();
+ setValue(val);
+ param_value_t::clearValueName();
setProvided(flag_as_provided);
- Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
@@ -670,65 +719,56 @@ namespace LLInitParam
}
// implicit conversion
- operator value_assignment_t() const { return get(); }
+ operator value_assignment_t() const { return param_value_t::getValue(); }
// explicit conversion
- value_assignment_t operator()() const { return get(); }
+ value_assignment_t operator()() const { return param_value_t::getValue(); }
protected:
- value_assignment_t get() const
- {
- return mData.mValue;
- }
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
+
if (src_typed_param.isProvided()
&& (overwrite || !dst_typed_param.isProvided()))
{
- dst_typed_param.mData.clearKey();
- dst_typed_param.set(src_typed_param.get());
+ dst_typed_param.clearValueName();
+ dst_typed_param.set(src_typed_param.getValue());
return true;
}
return false;
}
-
- struct Data : public key_cache_t
- {
- T mValue;
- };
-
- Data mData;
};
// parameter that is a block
template <typename T, typename NAME_VALUE_LOOKUP>
class TypedParam<T, NAME_VALUE_LOOKUP, false, true>
- : public T,
- public Param
+ : public Param,
+ public ParamValue<T, NAME_VALUE_LOOKUP>
{
public:
typedef const T value_const_t;
typedef T value_t;
- typedef value_const_t& value_const_ref_t;
- typedef value_const_ref_t value_assignment_t;
- typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+ typedef value_const_t& value_assignment_t;
typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
+ typedef NAME_VALUE_LOOKUP name_value_lookup_t;
+ typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_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),
- T(value)
+ param_value_t(value)
{
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
&deserializeParam,
&serializeParam,
validate_func,
&inspectParam,
- min_count, max_count);
+ min_count, max_count));
BaseBlock::addParam(block_descriptor, param_descriptor, name);
}
}
@@ -737,25 +777,27 @@ namespace LLInitParam
{
self_t& typed_param = static_cast<self_t&>(param);
// attempt to parse block...
- if(typed_param.deserializeBlock(parser, name_stack))
+ if(typed_param.deserializeBlock(parser, name_stack, generation))
{
- typed_param.mData.clearKey();
- typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.clearValueName();
+ typed_param.enclosingBlock().paramChanged(param, true);
+ typed_param.setProvided(true);
return true;
}
- if(!NAME_VALUE_LOOKUP::empty())
+ if(name_value_lookup_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (NAME_VALUE_LOOKUP::get(name, typed_param))
+ if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
{
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.mData.setKey(name);
- typed_param.mData.mKeyVersion = typed_param.getLastChangeVersion();
+ typed_param.enclosingBlock().paramChanged(param, true);
+ typed_param.setValueName(name);
+ typed_param.setProvided(true);
+ typed_param.mKeyVersion = typed_param.getLastChangeVersion();
return true;
}
@@ -767,13 +809,15 @@ namespace LLInitParam
static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
{
const self_t& typed_param = static_cast<const self_t&>(param);
+ if (!typed_param.isProvided()) return;
+
if (!name_stack.empty())
{
name_stack.back().second = parser.newParseGeneration();
}
- std::string key = typed_param.mData.getKey();
- if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion())
+ std::string key = typed_param.getValueName();
+ if (!key.empty() && typed_param.mKeyVersion == typed_param.getLastChangeVersion())
{
if (!parser.writeValue(key, name_stack))
{
@@ -790,33 +834,33 @@ namespace LLInitParam
{
// I am a param that is also a block, so just recurse into my contents
const self_t& typed_param = static_cast<const self_t&>(param);
- typed_param.inspectBlock(parser, name_stack);
+ typed_param.inspectBlock(parser, name_stack, min_count, max_count);
}
// a param-that-is-a-block is provided when the user has set one of its child params
// *and* the block as a whole validates
bool isProvided() const
{
- // only validate block when it hasn't already passed validation and user has supplied *some* value
- if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
+ // only validate block when it hasn't already passed validation with current data
+ if (Param::anyProvided() && param_value_t::mValidatedVersion < param_value_t::getLastChangeVersion())
{
// a sub-block is "provided" when it has been filled in enough to be valid
- mData.mValidated = T::validateBlock(false);
- mData.mValidatedVersion = T::getLastChangeVersion();
+ param_value_t::mValidated = param_value_t::validateBlock(false);
+ param_value_t::mValidatedVersion = param_value_t::getLastChangeVersion();
}
- return Param::anyProvided() && mData.mValidated;
+ return Param::anyProvided() && param_value_t::mValidated;
}
// assign block contents to this param-that-is-a-block
void set(value_assignment_t val, bool flag_as_provided = true)
{
- value_t::operator=(val);
- mData.clearKey();
+ setValue(val);
+ param_value_t::clearValueName();
// force revalidation of block by clearing known provided version
// next call to isProvided() will update provision status based on validity
- mData.mValidatedVersion = 0;
+ param_value_t::mValidatedVersion = -1;
setProvided(flag_as_provided);
- Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
@@ -828,10 +872,10 @@ namespace LLInitParam
}
// propagate changed status up to enclosing block
- /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+ /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
- T::setLastChangedParam(last_param, user_provided);
- Param::enclosingBlock().setLastChangedParam(*this, user_provided);
+ ParamValue<T, NAME_VALUE_LOOKUP>::paramChanged(changed_param, user_provided);
+ Param::enclosingBlock().paramChanged(*this, user_provided);
if (user_provided)
{
// a child param has been explicitly changed
@@ -841,41 +885,28 @@ namespace LLInitParam
}
// implicit conversion
- operator value_assignment_t() const { return get(); }
+ operator value_assignment_t() const { return param_value_t::getValue(); }
// explicit conversion
- value_assignment_t operator()() const { return get(); }
+ value_assignment_t operator()() const { return param_value_t::getValue(); }
protected:
- value_assignment_t get() const
- {
- return *this;
- }
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
- if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite))
+
+ if (src_typed_param.isProvided()
+ && (overwrite || !dst_typed_param.isProvided()))
{
- dst_typed_param.mData.clearKey();
- return true;
+ if (dst_typed_param.merge(param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+ {
+ dst_typed_param.clearValueName();
+ return true;
+ }
}
return false;
}
-
- struct Data : public key_cache_t
- {
- S32 mKeyVersion;
- mutable S32 mValidatedVersion;
- mutable bool mValidated; // lazy validation flag
-
- Data()
- : mKeyVersion(0),
- mValidatedVersion(0),
- mValidated(false)
- {}
- };
- Data mData;
};
// container of non-block parameters
@@ -885,29 +916,28 @@ namespace LLInitParam
{
public:
typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
- typedef typename std::vector<VALUE_TYPE> container_t;
+ typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
+ typedef typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
typedef VALUE_TYPE value_t;
- typedef value_t& value_ref_t;
- typedef const value_t& value_const_ref_t;
+ typedef NAME_VALUE_LOOKUP name_value_lookup_t;
- typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_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),
- mValues(value)
+ : Param(block_descriptor.mCurrentBlockPtr)
{
- mCachedKeys.resize(mValues.size());
+ std::copy(value.begin(), value.end(), std::back_inserter(mValues));
+
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
&deserializeParam,
&serializeParam,
validate_func,
&inspectParam,
- min_count, max_count);
+ min_count, max_count));
BaseBlock::addParam(block_descriptor, param_descriptor, name);
}
}
@@ -924,29 +954,22 @@ namespace LLInitParam
// attempt to read value directly
if (parser.readValue(value))
{
- typed_param.mValues.push_back(value);
- // save an empty name/value key as a placeholder
- typed_param.mCachedKeys.push_back(key_cache_t());
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.setProvided(true);
+ typed_param.add(value);
return true;
}
// try to parse a known named value
- if(!NAME_VALUE_LOOKUP::empty())
+ if(name_value_lookup_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues))
+ if (name_value_lookup_t::getValueFromName(name, typed_param.mValues))
{
- typed_param.mValues.push_back(value);
- typed_param.mCachedKeys.push_back(key_cache_t());
- typed_param.mCachedKeys.back().setKey(name);
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.setProvided(true);
+ typed_param.add(value);
+ typed_param.mValues.back().setValueName(name);
return true;
}
@@ -961,25 +984,27 @@ namespace LLInitParam
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided() || name_stack.empty()) return;
- const_iterator it = typed_param.mValues.begin();
- for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin();
- it != typed_param.mValues.end();
- ++key_it, ++it)
+ for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
+ it != end_it;
+ ++it)
{
- std::string key = key_it->get();
+ std::string key = it->getValue();
name_stack.back().second = parser.newParseGeneration();
- if(!key.empty())
+ if(key.empty())
+ // not parsed via name values, write out value directly
{
- if(!parser.writeValue(key, name_stack))
+ if (!parser.writeValue(*it, name_stack))
{
- return;
+ break;
}
}
- // not parse via name values, write out value directly
- else if (!parser.writeValue(*it, name_stack))
+ else
{
- return;
+ if(!parser.writeValue(key, name_stack))
+ {
+ break;
+ }
}
}
}
@@ -987,19 +1012,17 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
- if (NAME_VALUE_LOOKUP::getPossibleValues())
+ if (name_value_lookup_t::getPossibleValues())
{
- parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
+ parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
}
}
void set(value_assignment_t val, bool flag_as_provided = true)
{
mValues = val;
- mCachedKeys.clear();
- mCachedKeys.resize(mValues.size());
setProvided(flag_as_provided);
- Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
@@ -1011,23 +1034,23 @@ namespace LLInitParam
}
}
- value_ref_t add()
+ value_t& add()
{
- mValues.push_back(value_t());
- mCachedKeys.push_back(key_cache_t());
+ mValues.push_back(param_value_t(value_t()));
setProvided(true);
+ Param::enclosingBlock().paramChanged(*this, true);
return mValues.back();
}
- void add(value_const_ref_t item)
+ void add(const value_t& item)
{
- mValues.push_back(item);
- mCachedKeys.push_back(key_cache_t());
+ mValues.push_back(param_value_t(item));
setProvided(true);
+ Param::enclosingBlock().paramChanged(*this, true);
}
// implicit conversion
- operator value_assignment_t() const { return self_t::get(); }
+ operator value_assignment_t() const { return mValues; }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
@@ -1044,27 +1067,25 @@ namespace LLInitParam
}
protected:
- value_assignment_t get() const
- {
- return mValues;
- }
-
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
- if (src_typed_param.isProvided()
- && (overwrite || !dst_typed_param.isProvided()))
+ if (overwrite)
{
- dst_typed_param.set(src_typed_param.get());
- return true;
+ std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
}
- return false;
+ else
+ {
+ container_t new_values(src_typed_param.mValues);
+ std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
+ std::swap(dst_typed_param.mValues, new_values);
+ }
+ return true;
}
container_t mValues;
- std::vector<key_cache_t> mCachedKeys;
};
// container of block parameters
@@ -1074,80 +1095,76 @@ namespace LLInitParam
{
public:
typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
- typedef typename std::vector<VALUE_TYPE> container_t;
+ typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
+ typedef typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
-
typedef VALUE_TYPE value_t;
- typedef value_t& value_ref_t;
- typedef const value_t& value_const_ref_t;
-
- typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
+ 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),
- mValues(value),
- mLastParamGeneration(0)
+ mLastParseGeneration(0)
{
- mCachedKeys.resize(mValues.size());
+ std::copy(value.begin(), value.end(), back_inserter(mValues));
+
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
&mergeWith,
&deserializeParam,
&serializeParam,
validate_func,
&inspectParam,
- min_count, max_count);
+ min_count, max_count));
BaseBlock::addParam(block_descriptor, param_descriptor, name);
}
}
bool isProvided() const { return Param::anyProvided(); }
- value_ref_t operator[](S32 index) { return mValues[index]; }
- value_const_ref_t operator[](S32 index) const { return mValues[index]; }
-
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
self_t& typed_param = static_cast<self_t&>(param);
bool new_value = false;
- if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty())
+
+ if (generation != typed_param.mLastParseGeneration
+ || typed_param.mValues.empty())
{
new_value = true;
typed_param.mValues.push_back(value_t());
- typed_param.mCachedKeys.push_back(Data());
}
- value_ref_t value = typed_param.mValues.back();
+ param_value_t& value = typed_param.mValues.back();
// attempt to parse block...
- if(value.deserializeBlock(parser, name_stack))
+ if(value.deserializeBlock(parser, name_stack, generation))
{
if (new_value)
{ // successfully parsed new value, let's keep it
- typed_param.mLastParamGeneration = generation;
+ typed_param.mLastParseGeneration = generation;
}
- typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.enclosingBlock().paramChanged(param, true);
typed_param.setProvided(true);
return true;
}
- else if(!NAME_VALUE_LOOKUP::empty())
+ else if(name_value_lookup_t::valueNamesExist())
{
// try to parse a known named value
std::string name;
if (parser.readValue(name))
{
// try to parse a per type named value
- if (NAME_VALUE_LOOKUP::get(name, value))
+ if (name_value_lookup_t::getValueFromName(name, value.getValue()))
{
if (new_value)
{ // successfully parsed new value, let's keep it
- typed_param.mLastParamGeneration = generation;
+ typed_param.mLastParseGeneration = generation;
}
- typed_param.mCachedKeys.back().setKey(name);
- typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion();
- typed_param.enclosingBlock().setLastChangedParam(param, true);
+ typed_param.mValues.back().setValueName(name);
+ typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion();
+ typed_param.enclosingBlock().paramChanged(param, true);
typed_param.setProvided(true);
return true;
}
@@ -1158,7 +1175,6 @@ namespace LLInitParam
if (new_value)
{ // failed to parse new value, pop it off
typed_param.mValues.pop_back();
- typed_param.mCachedKeys.pop_back();
}
return false;
@@ -1169,26 +1185,22 @@ namespace LLInitParam
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided() || name_stack.empty()) return;
- const_iterator it = typed_param.mValues.begin();
- for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin();
- it != typed_param.mValues.end();
- ++key_it, ++it)
+ for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
+ it != end_it;
+ ++it)
{
name_stack.back().second = parser.newParseGeneration();
- std::string key = key_it->getKey();
- if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion())
+ std::string key = it->getValueName();
+ if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())
{
- if(!parser.writeValue(key, name_stack))
- {
- return;
- }
+ 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
- else if (!it->serializeBlock(parser, name_stack, NULL))
+ else
{
- return;
+ it->serializeBlock(parser, name_stack, NULL);
}
}
}
@@ -1196,16 +1208,14 @@ namespace LLInitParam
static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
{
// I am a vector of blocks, so describe my contents recursively
- value_t().inspectBlock(parser, name_stack);
+ param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
}
void set(value_assignment_t val, bool flag_as_provided = true)
{
mValues = val;
- mCachedKeys.clear();
- mCachedKeys.resize(mValues.size());
setProvided(flag_as_provided);
- Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
+ Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
@@ -1216,23 +1226,23 @@ namespace LLInitParam
}
}
- value_ref_t add()
+ value_t& add()
{
mValues.push_back(value_t());
- mCachedKeys.push_back(Data());
setProvided(true);
+ Param::enclosingBlock().paramChanged(*this, true);
return mValues.back();
}
- void add(value_const_ref_t item)
+ void add(const value_t& item)
{
mValues.push_back(item);
- mCachedKeys.push_back(Data());
setProvided(true);
+ Param::enclosingBlock().paramChanged(*this, true);
}
// implicit conversion
- operator value_assignment_t() const { return self_t::get(); }
+ operator value_assignment_t() const { return mValues; }
typedef typename container_t::iterator iterator;
typedef typename container_t::const_iterator const_iterator;
@@ -1246,8 +1256,8 @@ namespace LLInitParam
U32 numValidElements() const
{
U32 count = 0;
- for (const_iterator it = mValues.begin();
- it != mValues.end();
+ for (const_iterator it = mValues.begin(), end_it = mValues.end();
+ it != end_it;
++it)
{
if(it->validateBlock(false)) count++;
@@ -1256,43 +1266,35 @@ namespace LLInitParam
}
protected:
- value_assignment_t get() const
- {
- return mValues;
- }
static bool mergeWith(Param& dst, const Param& src, bool overwrite)
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
- if (src_typed_param.isProvided()
- && (overwrite || !dst_typed_param.isProvided()))
+ if (overwrite)
{
- dst_typed_param.set(src_typed_param.get());
- return true;
+ std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
}
- return false;
+ else
+ {
+ container_t new_values(src_typed_param.mValues);
+ std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
+ std::swap(dst_typed_param.mValues, new_values);
+ }
+ return true;
}
- struct Data : public key_cache_t
- {
- S32 mKeyVersion; // version of block for which key was last valid
-
- Data() : mKeyVersion(0) {}
- };
-
container_t mValues;
- std::vector<Data> mCachedKeys;
- S32 mLastParamGeneration;
+ S32 mLastParseGeneration;
};
template <typename DERIVED_BLOCK>
class Choice : public BaseBlock
{
- typedef Choice<DERIVED_BLOCK> self_t;
- typedef Choice<DERIVED_BLOCK> enclosing_block_t;
+ typedef Choice<DERIVED_BLOCK> self_t;
+ typedef Choice<DERIVED_BLOCK> enclosing_block_t;
LOG_CLASS(self_t);
public:
@@ -1321,9 +1323,9 @@ namespace LLInitParam
}
// clear out old choice when param has changed
- /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+ /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
- param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&last_param);
+ param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&changed_param);
// if we have a new choice...
if (changed_param_handle != mCurChoice)
{
@@ -1335,7 +1337,7 @@ namespace LLInitParam
}
mCurChoice = changed_param_handle;
}
- BaseBlock::setLastChangedParam(last_param, user_provided);
+ BaseBlock::paramChanged(changed_param, user_provided);
}
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
@@ -1358,20 +1360,21 @@ namespace LLInitParam
friend class Choice<DERIVED_BLOCK>;
typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
typedef typename super_t::value_assignment_t value_assignment_t;
- explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get())
+ explicit Alternative(const char* name, value_assignment_t val = defaultValue<T>())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
mOriginalValue(val)
{
// assign initial choice to first declared option
DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
- if (LL_UNLIKELY(
- DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
- && blockp->mCurChoice == 0))
+ if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
{
- blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
+ if(blockp->mCurChoice == 0)
+ {
+ blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
+ }
}
}
@@ -1390,7 +1393,7 @@ namespace LLInitParam
{
if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
{
- return super_t::get();
+ return super_t::getValue();
}
return mOriginalValue;
}
@@ -1399,7 +1402,7 @@ namespace LLInitParam
{
if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
{
- return super_t::get();
+ return super_t::getValue();
}
return mOriginalValue;
}
@@ -1433,8 +1436,8 @@ namespace LLInitParam
class Block
: public BASE_BLOCK
{
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
- typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
+ typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
public:
typedef BASE_BLOCK base_block_t;
@@ -1442,13 +1445,13 @@ namespace LLInitParam
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return BaseBlock::merge(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->merge(selfBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return BaseBlock::merge(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->merge(selfBlockDescriptor(), other, false);
}
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
@@ -1468,10 +1471,10 @@ namespace LLInitParam
class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
typedef typename super_t::value_assignment_t value_assignment_t;
- explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
+ explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
{
//#pragma message("Parsing LLInitParam::Block::Optional")
@@ -1483,7 +1486,7 @@ namespace LLInitParam
return *this;
}
- DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+ DERIVED_BLOCK& operator()(value_assignment_t val)
{
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1495,12 +1498,12 @@ namespace LLInitParam
class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
{
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::value_assignment_t value_assignment_t;
// mandatory parameters require a name to be parseable
- explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
+ explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
{}
@@ -1529,15 +1532,15 @@ namespace LLInitParam
class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
{
public:
- typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBaseBlock<T>::value> super_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::container_t container_t;
typedef typename super_t::value_assignment_t value_assignment_t;
typedef typename super_t::iterator iterator;
typedef typename super_t::const_iterator const_iterator;
- explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
- : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
+ explicit Multiple(const char* name = "")
+ : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount(), RANGE::maxCount())
{}
Multiple& operator=(value_assignment_t val)
@@ -1545,7 +1548,7 @@ namespace LLInitParam
set(val);
return *this;
}
-
+
DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
{
super_t::set(val);
@@ -1559,6 +1562,96 @@ namespace LLInitParam
}
};
+ template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+ class Batch : private TypedParam<T, NAME_VALUE_LOOKUP, false>
+ {
+ public:
+ typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
+ typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<param_value_t>::value> super_t;
+ typedef Batch<T, RANGE, NAME_VALUE_LOOKUP> self_t;
+ typedef typename super_t::value_assignment_t value_assignment_t;
+ typedef typename super_t::value_t value_t;
+
+ struct BatchDefaultValue : public ParamDescriptor::UserData
+ {
+ BatchDefaultValue(const T& value)
+ : mValue(value)
+ {}
+
+ T mValue;
+ };
+
+ explicit Batch(const char* name, value_assignment_t val)
+ : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
+ mLastParseGeneration(-1)
+ {
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this);
+
+ if (param_descriptorp)
+ {
+ param_descriptorp->mDeserializeFunc = &deserializeParam;
+ param_descriptorp->mUserData = new BatchDefaultValue(new param_value_t(val));
+ }
+ }
+ }
+
+ explicit Batch(const char* name = "")
+ : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, defaultValue<T>(), NULL, 0, 1),
+ mLastParseGeneration(-1)
+ {
+ BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+ if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
+ {
+ ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this);
+
+ if (param_descriptorp)
+ {
+ param_descriptorp->mDeserializeFunc = &deserializeParam;
+ }
+ }
+ }
+
+ Batch& operator=(value_assignment_t val)
+ {
+ set(val);
+ return *this;
+ }
+
+ DERIVED_BLOCK& operator()(value_assignment_t val)
+ {
+ super_t::set(val);
+ return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+ }
+
+ using super_t::operator();
+
+ private:
+ static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ {
+ self_t& typed_param = static_cast<self_t&>(param);
+
+ if (generation != typed_param.mLastParseGeneration)
+ {
+ ParamDescriptorPtr descriptor = typed_param.enclosingBlock().findParamDescriptor(param);
+ if (descriptor && static_cast<BatchDefaultValue*>(descriptor->mUserData))
+ {
+ static_cast<param_value_t&>(typed_param) = (static_cast<BatchDefaultValue*>(descriptor->mUserData))->mValue;
+ }
+ else
+ {
+ static_cast<param_value_t&>(typed_param) = param_value_t(value_t());
+ }
+ typed_param.mLastParseGeneration = generation;
+ }
+ return super_t::deserializeParam(param, parser, name_stack, generation);
+ }
+
+ S32 mLastParseGeneration;
+ };
+
class Deprecated : public Param
{
public:
@@ -1568,13 +1661,14 @@ namespace LLInitParam
BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
{
- ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+ ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+ block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
NULL,
&deserializeParam,
NULL,
NULL,
NULL,
- 0, S32_MAX);
+ 0, S32_MAX));
BaseBlock::addParam(block_descriptor, param_descriptor, name);
}
}
@@ -1602,137 +1696,91 @@ namespace LLInitParam
}
};
- template<typename T, typename DERIVED = TypedParam<T> >
- class BlockValue
- : public Block<TypedParam<T, TypeValues<T>, false> >,
- public Param
+ template<typename T>
+ class CustomParamValue
+ : public Block<ParamValue<T, TypeValues<T> > >,
+ public TypeValues<T>
{
public:
typedef enum e_value_age
{
- OLDER_THAN_BLOCK, // mData.mValue needs to be refreshed from the block parameters
- NEWER_THAN_BLOCK, // mData.mValue holds the authoritative value (which has been replicated to the block parameters via setBlockFromValue)
- SAME_AS_BLOCK // mData.mValue is derived from the block parameters, which are authoritative
+ VALUE_NEEDS_UPDATE, // mValue needs to be refreshed from the block parameters
+ VALUE_AUTHORITATIVE, // mValue holds the authoritative value (which has been replicated to the block parameters via updateBlockFromValue)
+ BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
} EValueAge;
- typedef BlockValue<T> self_t;
- typedef Block<TypedParam<T, TypeValues<T>, false> > block_t;
- typedef const T& value_const_ref_t;
- typedef value_const_ref_t value_assignment_t;
- typedef typename TypeValues<T>::KeyCache key_cache_t;
-
- BlockValue(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),
- mData(value, NEWER_THAN_BLOCK)
- {
- if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
- {
- ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
- &mergeWith,
- &deserializeParam,
- &serializeParam,
- validate_func,
- &inspectParam,
- min_count, max_count);
- BaseBlock::addParam(block_descriptor, param_descriptor, name);
- }
- }
+ typedef ParamValue<T, TypeValues<T> > derived_t;
+ typedef CustomParamValue<T> self_t;
+ typedef Block<derived_t> block_t;
+ typedef const T& value_assignment_t;
- // implicit conversion
- operator value_assignment_t() const { return get(); }
- // explicit conversion
- value_assignment_t operator()() const { return get(); }
+ CustomParamValue(const T& value = T())
+ : mValue(value),
+ mValueAge(VALUE_AUTHORITATIVE),
+ mKeyVersion(0),
+ mValidatedVersion(-1)
+ {}
- static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+ bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation)
{
- DERIVED& typed_param = static_cast<DERIVED&>(param);
+ derived_t& typed_param = static_cast<derived_t&>(*this);
// type to apply parse direct value T
if (name_stack.first == name_stack.second)
{
- if(parser.readValue(typed_param.mData.mValue))
+ if(parser.readValue(typed_param.mValue))
{
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.setProvided(true);
- typed_param.mData.clearKey();
- typed_param.mData.mValueAge = NEWER_THAN_BLOCK;
- typed_param.setBlockFromValue();
+ typed_param.clearValueName();
+ typed_param.mValueAge = VALUE_AUTHORITATIVE;
+ typed_param.updateBlockFromValue();
return true;
}
-
- if(!TypeValues<T>::empty())
- {
- // try to parse a known named value
- std::string name;
- if (parser.readValue(name))
- {
- // try to parse a per type named value
- if (TypeValues<T>::get(name, typed_param.mData.mValue))
- {
- typed_param.mData.setKey(name);
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.setProvided(true);
- typed_param.mData.mValueAge = NEWER_THAN_BLOCK;
- typed_param.setBlockFromValue();
-
- return true;
- }
- }
- }
}
// fall back on parsing block components for T
// if we deserialized at least one component...
- if (typed_param.BaseBlock::deserializeBlock(parser, name_stack))
+ if (typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation))
{
- // ...our block is provided, and considered changed
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.setProvided(true);
return true;
}
+
return false;
}
- static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
+ void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const
{
- const self_t& typed_param = static_cast<const self_t&>(param);
+ const self_t& typed_param = static_cast<const self_t&>(*this);
+ const self_t* diff_param = static_cast<const self_t*>(diff_block);
- if (!typed_param.isProvided()) return;
-
- std::string key = typed_param.mData.getKey();
+ std::string key = typed_param.getValueName();
// first try to write out name of name/value pair
if (!key.empty())
{
- if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
+ if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
{
- if (!parser.writeValue(key, name_stack))
- {
- return;
- }
+ parser.writeValue(key, name_stack);
}
}
// then try to serialize value directly
- else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))
+ else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
{
- if (parser.writeValue(typed_param.mData.mValue, name_stack))
+ if (!parser.writeValue(typed_param.getValue(), name_stack))
{
- return;
+ //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
+ // since these tend to be viewed as the constructor arguments for the value T. It seems
+ // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
+ // not the individual components. This way <color red="0" green="1" blue="0"/> will not
+ // be exported as <color green="1"/>, since it was probably the intent of the user to
+ // be specific about the RGB color values. This also fixes an issue where we distinguish
+ // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
+ block_t::serializeBlock(parser, name_stack, NULL);
}
-
- //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
- // since these tend to be viewed as the constructor arguments for the value T. It seems
- // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
- // not the individual components. This way <color red="0" green="1" blue="0"/> will not
- // be exported as <color green="1"/>, since it was probably the intent of the user to
- // be specific about the RGB color values. This also fixes an issue where we distinguish
- // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
- typed_param.BaseBlock::serializeBlock(parser, name_stack, NULL);
}
}
- static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
+ bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
{
// first, inspect with actual type...
parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
@@ -1742,25 +1790,19 @@ namespace LLInitParam
parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
}
// then recursively inspect contents...
- const self_t& typed_param = static_cast<const self_t&>(param);
- typed_param.inspectBlock(parser, name_stack);
+ return block_t::inspectBlock(parser, name_stack, min_count, max_count);
}
-
- bool isProvided() const
+ bool validateBlock(bool emit_errors = true) const
{
- if (!Param::anyProvided()) return false;
-
- // block has an updated parameter
- // if cached value is stale, regenerate from params
- if (mData.mValueAge == OLDER_THAN_BLOCK)
+ if (mValueAge == VALUE_NEEDS_UPDATE)
{
- if (block_t::validateBlock(false))
+ if (block_t::validateBlock(emit_errors))
{
- static_cast<const DERIVED*>(this)->setValueFromBlock();
// clear stale keyword associated with old value
- mData.clearKey();
- mData.mValueAge = SAME_AS_BLOCK;
+ TypeValues<T>::clearValueName();
+ mValueAge = BLOCK_AUTHORITATIVE;
+ static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
return true;
}
else
@@ -1777,104 +1819,75 @@ namespace LLInitParam
}
}
- void set(value_assignment_t val, bool flag_as_provided = true)
- {
- Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
-
- // set param version number to be up to date, so we ignore block contents
- mData.mValueAge = NEWER_THAN_BLOCK;
-
- mData.mValue = val;
- mData.clearKey();
- setProvided(flag_as_provided);
- static_cast<DERIVED*>(this)->setBlockFromValue();
- }
-
- void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
- {
- // don't override any user provided value
- if (!isProvided())
- {
- set(val, flag_as_provided);
- }
- }
-
// propagate change status up to enclosing block
- /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
+ /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
- BaseBlock::setLastChangedParam(last_param, user_provided);
- Param::enclosingBlock().setLastChangedParam(*this, user_provided);
+ BaseBlock::paramChanged(changed_param, user_provided);
if (user_provided)
- {
- setProvided(true); // some component provided
+ {
// a parameter changed, so our value is out of date
- mData.mValueAge = OLDER_THAN_BLOCK;
+ mValueAge = VALUE_NEEDS_UPDATE;
}
}
-
- protected:
- value_assignment_t get() const
+
+ void setValue(value_assignment_t val)
{
- // if some parameters were provided, issue warnings on invalid blocks
- if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
- {
- // go ahead and issue warnings at this point if any param is invalid
- if(block_t::validateBlock(true))
- {
- static_cast<const DERIVED*>(this)->setValueFromBlock();
- mData.clearKey();
- mData.mValueAge = SAME_AS_BLOCK;
- }
- }
-
- return mData.mValue;
+ derived_t& typed_param = static_cast<derived_t&>(*this);
+ // set param version number to be up to date, so we ignore block contents
+ mValueAge = VALUE_AUTHORITATIVE;
+ mValue = val;
+ typed_param.clearValueName();
+ static_cast<derived_t*>(const_cast<self_t*>(this))->updateBlockFromValue();
}
+ value_assignment_t getValue() const
+ {
+ validateBlock(true);
+ return mValue;
+ }
- struct Data : public key_cache_t
+ T& getValue()
{
- Data(const T& value, EValueAge age)
- : mValue(value),
- mValueAge(age)
- {}
+ validateBlock(true);
+ return mValue;
+ }
- T mValue;
- EValueAge mValueAge;
- };
+ S32 mKeyVersion;
- // mutable to allow lazy updates on get
- mutable Data mData;
+ protected:
- private:
- static bool mergeWith(Param& dst, const Param& src, bool overwrite)
+ // use this from within updateValueFromBlock() to set the value without making it authoritative
+ void updateValue(value_assignment_t value)
{
- const DERIVED& src_typed_param = static_cast<const DERIVED&>(src);
- DERIVED& dst_typed_param = static_cast<DERIVED&>(dst);
+ mValue = value;
+ }
- if (src_typed_param.isProvided()
- && (overwrite || !dst_typed_param.isProvided()))
+ bool merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ {
+ const derived_t& src_typed_param = static_cast<const derived_t&>(other);
+
+ if (src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
{
- if (src_typed_param.mData.mValueAge == NEWER_THAN_BLOCK)
- {
- // copy value over
- dst_typed_param.set(src_typed_param.get());
- }
- else
- {
- // merge individual parameters into destination
- dst_typed_param.merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
- }
+ // copy value over
+ setValue(src_typed_param.getValue());
return true;
}
- return false;
+ else
+ {
+ // merge individual parameters into destination
+ return block_t::merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
+ }
}
- };
- template<>
- struct ParamCompare<LLSD, false>
- {
- static bool equals(const LLSD &a, const LLSD &b);
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
+
+ private:
+
+ mutable T mValue;
+ mutable EValueAge mValueAge;
};
}
+
#endif // LL_LLPARAM_H
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d98f0da1c2..636f6e65fe 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12613,6 +12613,39 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>EnableInventory</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable opening inventory from web link</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>EnableSearch</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable opening search from web link</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>EnableAppearance</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable opening appearance from web link</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>SearchFromAddressBar</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml
index 490da2c9d4..bc97ec00e9 100644
--- a/indra/newview/app_settings/settings_minimal.xml
+++ b/indra/newview/app_settings/settings_minimal.xml
@@ -303,6 +303,39 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>EnableInventory</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable opening inventory from web link</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>EnableSearch</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable opening search from web link</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>EnableAppearance</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable opening appearance from web link</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DoubleClickShowWorldMap</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 1cf552e42c..f9e850899a 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -110,6 +110,12 @@ public:
{
// support secondlife:///app/appearance/show, but for now we just
// make all secondlife:///app/appearance SLapps behave this way
+ if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAppearance"))
+ {
+ LLNotificationsUtil::add("NoAppearance", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD());
return true;
}
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index c7fbdd5745..d76e7885bc 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -325,122 +325,51 @@ void LLFloaterImagePreview::draw()
bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
{
std::string exten = gDirUtilp->getExtension(src_filename);
-
- U32 codec = IMG_CODEC_INVALID;
- std::string temp_str;
- if( exten == "bmp")
- {
- codec = IMG_CODEC_BMP;
- }
- else if( exten == "tga")
- {
- codec = IMG_CODEC_TGA;
- }
- else if( exten == "jpg" || exten == "jpeg")
- {
- codec = IMG_CODEC_JPEG;
- }
- else if( exten == "png" )
- {
- codec = IMG_CODEC_PNG;
- }
+ U32 codec = LLImageBase::getCodecFromExtension(exten);
LLImageDimensionsInfo image_info;
- if(!image_info.load(src_filename,codec))
+ if (!image_info.load(src_filename,codec))
{
mImageLoadError = image_info.getLastError();
return false;
}
S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
- S32 max_heigh = gSavedSettings.getS32("max_texture_dimension_Y");
+ S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
- if(image_info.getWidth() > max_width|| image_info.getHeight() > max_heigh)
+ if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
{
LLStringUtil::format_map_t args;
args["WIDTH"] = llformat("%d", max_width);
- args["HEIGHT"] = llformat("%d", max_heigh);
+ args["HEIGHT"] = llformat("%d", max_height);
mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
return false;
}
-
+ // Load the image
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
+ if (image.isNull())
+ {
+ return false;
+ }
+ if (!image->load(src_filename))
+ {
+ return false;
+ }
+ // Decompress or expand it in a raw image structure
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
-
- switch (codec)
+ if (!image->decode(raw_image, 0.0f))
{
- case IMG_CODEC_BMP:
- {
- LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
-
- if (!bmp_image->load(src_filename))
- {
- return false;
- }
-
- if (!bmp_image->decode(raw_image, 0.0f))
- {
- return false;
- }
- }
- break;
- case IMG_CODEC_TGA:
- {
- LLPointer<LLImageTGA> tga_image = new LLImageTGA;
-
- if (!tga_image->load(src_filename))
- {
- return false;
- }
-
- if (!tga_image->decode(raw_image))
- {
- return false;
- }
-
- if( (tga_image->getComponents() != 3) &&
- (tga_image->getComponents() != 4) )
- {
- tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." );
- return false;
- }
- }
- break;
- case IMG_CODEC_JPEG:
- {
- LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG;
-
- if (!jpeg_image->load(src_filename))
- {
- return false;
- }
-
- if (!jpeg_image->decode(raw_image, 0.0f))
- {
- return false;
- }
- }
- break;
- case IMG_CODEC_PNG:
- {
- LLPointer<LLImagePNG> png_image = new LLImagePNG;
-
- if (!png_image->load(src_filename))
- {
- return false;
- }
-
- if (!png_image->decode(raw_image, 0.0f))
- {
- return false;
- }
- }
- break;
- default:
return false;
}
-
+ // Check the image constraints
+ if ((image->getComponents() != 3) && (image->getComponents() != 4))
+ {
+ image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
+ return false;
+ }
+
raw_image->biasedScaleToPowerOfTwo(1024);
mRawImagep = raw_image;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2041fac8d8..d5806e375c 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -31,6 +31,7 @@
#include "llfloaterreg.h"
#include "llfloatersearch.h"
#include "llmediactrl.h"
+#include "llnotificationsutil.h"
#include "lllogininstance.h"
#include "lluri.h"
#include "llagent.h"
@@ -46,6 +47,12 @@ public:
LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
+ if (!LLUI::sSettingGroups["config"]->getBOOL("EnableSearch"))
+ {
+ LLNotificationsUtil::add("NoSearch", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
const size_t parts = tokens.size();
// get the (optional) category for the search
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index abcd8588dc..36c5d12897 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -558,6 +558,18 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
requested_options.append("buddy-list");
requested_options.append("newuser-config");
requested_options.append("ui-config");
+
+ //send this info to login.cgi for stats gathering
+ //since viewerstats isn't reliable enough
+ if (gSavedSettings.getString("SessionSettingsFile").empty())
+ {
+ requested_options.append("advanced-mode");
+ }
+ else
+ {
+ requested_options.append("basic-mode");
+ }
+
#endif
requested_options.append("max-agent-groups");
requested_options.append("map-server-url");
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 6cfb708112..18d6731fcb 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -143,10 +143,7 @@ void LLPreviewTexture::onSaveAsBtn(void* data)
void LLPreviewTexture::draw()
{
- if (mUpdateDimensions)
- {
- updateDimensions();
- }
+ updateDimensions();
LLPreview::draw();
@@ -396,27 +393,32 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
void LLPreviewTexture::updateDimensions()
{
if (!mImage)
+ {
return;
-
- if(mImage->getFullWidth() == 0 || mImage->getFullHeight() == 0)
+ }
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
{
return;
}
- mUpdateDimensions = FALSE;
-
- getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth()));
+ // Update the width/height display every time
+ getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth()));
getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight()));
-
- //reshape floater
- reshape(getRect().getWidth(), getRect().getHeight());
+ // Reshape the floater only when required
+ if (mUpdateDimensions)
+ {
+ mUpdateDimensions = FALSE;
+
+ //reshape floater
+ reshape(getRect().getWidth(), getRect().getHeight());
- gFloaterView->adjustToFitScreen(this, FALSE);
+ gFloaterView->adjustToFitScreen(this, FALSE);
- LLRect dim_rect(getChildView("dimensions")->getRect());
- LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect());
- getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft);
+ LLRect dim_rect(getChildView("dimensions")->getRect());
+ LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect());
+ getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft);
+ }
}
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 4f18ee1da2..e4c2293938 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -1192,6 +1192,38 @@ void LLSideTray::reshape(S32 width, S32 height, BOOL called_from_parent)
arrange();
}
+// This is just LLView::findChildView specialized to restrict the search to LLPanels.
+// Optimization for EXT-4068 to avoid searching down to the individual item level
+// when inventories are large.
+LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse)
+{
+ for (LLView::child_list_const_iter_t child_it = panel->beginChild();
+ child_it != panel->endChild(); ++child_it)
+ {
+ LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it);
+ if (!child_panel)
+ continue;
+ if (child_panel->getName() == name)
+ return child_panel;
+ }
+ if (recurse)
+ {
+ for (LLView::child_list_const_iter_t child_it = panel->beginChild();
+ child_it != panel->endChild(); ++child_it)
+ {
+ LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it);
+ if (!child_panel)
+ continue;
+ LLPanel *found_panel = findChildPanel(child_panel,name,recurse);
+ if (found_panel)
+ {
+ return found_panel;
+ }
+ }
+ }
+ return NULL;
+}
+
/**
* Activate tab with "panel_name" panel
* if no such tab - return false, otherwise true.
@@ -1221,23 +1253,50 @@ LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& para
return new_panel;
}
-void LLSideTray::hidePanel(const std::string& panel_name)
+bool LLSideTray::hidePanel(const std::string& panel_name)
{
+ bool panelHidden = false;
+
LLPanel* panelp = getPanel(panel_name);
+
if (panelp)
{
- if(isTabAttached(panel_name))
+ LLView* parentp = panelp->getParent();
+
+ // Collapse the side bar if the panel or the panel's parent is an attached tab
+ if (isTabAttached(panel_name) || (parentp && isTabAttached(parentp->getName())))
{
collapseSideBar();
+ panelHidden = true;
}
else
{
- LLFloaterReg::hideInstance("side_bar_tab", panel_name);
+ panelHidden = LLFloaterReg::hideInstance("side_bar_tab", panel_name);
+
+ if (!panelHidden)
+ {
+ // Look up the panel in the list of detached tabs.
+ for (child_vector_const_iter_t child_it = mDetachedTabs.begin(); child_it != mDetachedTabs.end(); ++child_it)
+ {
+ LLPanel *detached_panel = dynamic_cast<LLPanel*>(*child_it);
+
+ if (detached_panel)
+ {
+ // Hide this detached panel if it is a parent of our panel
+ if (findChildPanel(detached_panel, panel_name, true) != NULL)
+ {
+ panelHidden = LLFloaterReg::hideInstance("side_bar_tab", detached_panel->getName());
+ break;
+ }
+ }
+ }
+ }
}
}
+
+ return panelHidden;
}
-
void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name, const LLSD& params)
{
if(!sub_panel)
@@ -1255,38 +1314,6 @@ void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name,
}
}
-// This is just LLView::findChildView specialized to restrict the search to LLPanels.
-// Optimization for EXT-4068 to avoid searching down to the individual item level
-// when inventories are large.
-LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse)
-{
- for (LLView::child_list_const_iter_t child_it = panel->beginChild();
- child_it != panel->endChild(); ++child_it)
- {
- LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it);
- if (!child_panel)
- continue;
- if (child_panel->getName() == name)
- return child_panel;
- }
- if (recurse)
- {
- for (LLView::child_list_const_iter_t child_it = panel->beginChild();
- child_it != panel->endChild(); ++child_it)
- {
- LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it);
- if (!child_panel)
- continue;
- LLPanel *found_panel = findChildPanel(child_panel,name,recurse);
- if (found_panel)
- {
- return found_panel;
- }
- }
- }
- return NULL;
-}
-
LLPanel* LLSideTray::getPanel(const std::string& panel_name)
{
// Look up the panel in the list of detached tabs.
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 1dddd9e9bc..46765bfbcc 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -104,7 +104,7 @@ public:
*/
LLPanel* showPanel (const std::string& panel_name, const LLSD& params = LLSD());
- void hidePanel (const std::string& panel_name);
+ bool hidePanel (const std::string& panel_name);
/**
* Toggling Side Tray tab which contains "sub_panel" child of "panel_name" panel.
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 95bd210ae3..06e0d17b8c 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -639,6 +639,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
if (click_action == CLICK_ACTION_NONE // not doing 1-click action
&& gSavedSettings.getBOOL("ClickToWalk") // click to walk enabled
&& !gAgent.getFlying() // don't auto-navigate while flying until that works
+ && !gAgentAvatarp->isSitting()
&& !mBlockClickToWalk // another behavior hasn't cancelled click to walk
&& !mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick
&& (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 42750f8b3f..9e58acdcd3 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -183,6 +183,12 @@ public:
return false;
}
+ if (!LLUI::sSettingGroups["config"]->getBOOL("EnableInventory"))
+ {
+ LLNotificationsUtil::add("NoInventory", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
// support secondlife:///app/inventory/show
if (params[0].asString() == "show")
{
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index fda291f3c1..2cf8dbec89 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -493,6 +493,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
LLSD args;
std::string exten = gDirUtilp->getExtension(src_filename);
+ U32 codec = LLImageBase::getCodecFromExtension(exten);
LLAssetType::EType asset_type = LLAssetType::AT_NONE;
std::string error_message;
@@ -510,66 +511,20 @@ void upload_new_resource(const std::string& src_filename, std::string name,
upload_error(error_message, "NoFileExtension", filename, args);
return;
}
- else if( exten == "bmp")
+ else if (codec != IMG_CODEC_INVALID)
{
+ // It's an image file, the upload procedure is the same for all
asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerTextureList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_BMP ))
+ if (!LLViewerTextureList::createUploadFile(src_filename, filename, codec ))
{
error_message = llformat( "Problem with file %s:\n\n%s\n",
- src_filename.c_str(), LLImage::getLastError().c_str());
+ src_filename.c_str(), LLImage::getLastError().c_str());
args["FILE"] = src_filename;
args["ERROR"] = LLImage::getLastError();
upload_error(error_message, "ProblemWithFile", filename, args);
return;
}
}
- else if( exten == "tga")
- {
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerTextureList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_TGA ))
- {
- error_message = llformat("Problem with file %s:\n\n%s\n",
- src_filename.c_str(), LLImage::getLastError().c_str());
- args["FILE"] = src_filename;
- args["ERROR"] = LLImage::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return;
- }
- }
- else if( exten == "jpg" || exten == "jpeg")
- {
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerTextureList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_JPEG ))
- {
- error_message = llformat("Problem with file %s:\n\n%s\n",
- src_filename.c_str(), LLImage::getLastError().c_str());
- args["FILE"] = src_filename;
- args["ERROR"] = LLImage::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return;
- }
- }
- else if( exten == "png")
- {
- asset_type = LLAssetType::AT_TEXTURE;
- if (!LLViewerTextureList::createUploadFile(src_filename,
- filename,
- IMG_CODEC_PNG ))
- {
- error_message = llformat("Problem with file %s:\n\n%s\n",
- src_filename.c_str(), LLImage::getLastError().c_str());
- args["FILE"] = src_filename;
- args["ERROR"] = LLImage::getLastError();
- upload_error(error_message, "ProblemWithFile", filename, args);
- return;
- }
- }
else if(exten == "wav")
{
asset_type = LLAssetType::AT_SOUND; // tag it as audio
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 06f6ff23c2..5afed721ac 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -927,99 +927,43 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
const U8 codec)
-{
- // First, load the image.
+{
+ // Load the image
+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
+ if (image.isNull())
+ {
+ return FALSE;
+ }
+ if (!image->load(filename))
+ {
+ return FALSE;
+ }
+ // Decompress or expand it in a raw image structure
LLPointer<LLImageRaw> raw_image = new LLImageRaw;
-
- switch (codec)
+ if (!image->decode(raw_image, 0.0f))
{
- case IMG_CODEC_BMP:
- {
- LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
-
- if (!bmp_image->load(filename))
- {
- return FALSE;
- }
-
- if (!bmp_image->decode(raw_image, 0.0f))
- {
- return FALSE;
- }
- }
- break;
- case IMG_CODEC_TGA:
- {
- LLPointer<LLImageTGA> tga_image = new LLImageTGA;
-
- if (!tga_image->load(filename))
- {
- return FALSE;
- }
-
- if (!tga_image->decode(raw_image))
- {
- return FALSE;
- }
-
- if( (tga_image->getComponents() != 3) &&
- (tga_image->getComponents() != 4) )
- {
- tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." );
- return FALSE;
- }
- }
- break;
- case IMG_CODEC_JPEG:
- {
- LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG;
-
- if (!jpeg_image->load(filename))
- {
- return FALSE;
- }
-
- if (!jpeg_image->decode(raw_image, 0.0f))
- {
- return FALSE;
- }
- }
- break;
- case IMG_CODEC_PNG:
- {
- LLPointer<LLImagePNG> png_image = new LLImagePNG;
-
- if (!png_image->load(filename))
- {
- return FALSE;
- }
-
- if (!png_image->decode(raw_image, 0.0f))
- {
- return FALSE;
- }
- }
- break;
- default:
- return FALSE;
+ return FALSE;
}
-
- LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
-
- if( !compressedImage->save(out_filename) )
+ // Check the image constraints
+ if ((image->getComponents() != 3) && (image->getComponents() != 4))
{
- llinfos << "Couldn't create output file " << out_filename << llendl;
+ image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
return FALSE;
}
-
- // test to see if the encode and save worked.
+ // Convert to j2c (JPEG2000) and save the file locally
+ LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
+ if (!compressedImage->save(out_filename))
+ {
+ llinfos << "Couldn't create output file : " << out_filename << llendl;
+ return FALSE;
+ }
+ // Test to see if the encode and save worked
LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
- if( !integrity_test->loadAndValidate( out_filename ) )
+ if (!integrity_test->loadAndValidate( out_filename ))
{
- llinfos << "Image: " << out_filename << " is corrupt." << llendl;
+ llinfos << "Image file : " << out_filename << " is corrupt" << llendl;
return FALSE;
}
-
return TRUE;
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 4305349ea2..e020296842 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3968,7 +3968,9 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p
return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
}
-// Saves the image from the screen to the specified filename and path.
+// Saves the image from the screen to a raw image
+// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
+// the results over to the final raw image.
BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,
BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)
{
@@ -3986,8 +3988,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
// Hide all the UI widgets first and draw a frame
BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
- show_ui = show_ui ? TRUE : FALSE;
-
if ( prev_draw_ui != show_ui)
{
LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
@@ -4007,55 +4007,49 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
// from window
LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw();
- S32 snapshot_width = window_rect.getWidth();
+ S32 snapshot_width = window_rect.getWidth();
S32 snapshot_height = window_rect.getHeight();
// SNAPSHOT
- S32 window_width = snapshot_width;
+ S32 window_width = snapshot_width;
S32 window_height = snapshot_height;
+ // Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested
if (show_ui)
{
- image_width = llmin(image_width, window_width);
+ // If the user wants the UI, limit the output size to the available screen size
+ image_width = llmin(image_width, window_width);
image_height = llmin(image_height, window_height);
}
F32 scale_factor = 1.0f ;
- if(!keep_window_aspect) //image cropping
- {
+ if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
+ {
+ // if image cropping or need to enlarge the scene, compute a scale_factor
F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
- snapshot_width = (S32)(ratio * image_width) ;
+ snapshot_width = (S32)(ratio * image_width) ;
snapshot_height = (S32)(ratio * image_height) ;
scale_factor = llmax(1.0f, 1.0f / ratio) ;
}
- else //the scene(window) proportion needs to be maintained.
- {
- if(image_width > window_width || image_height > window_height) //need to enlarge the scene
- {
- F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
- snapshot_width = (S32)(ratio * image_width) ;
- snapshot_height = (S32)(ratio * image_height) ;
- scale_factor = llmax(1.0f, 1.0f / ratio) ;
- }
- }
if (show_ui && scale_factor > 1.f)
{
+ // Note: we should never get there...
llwarns << "over scaling UI not supported." << llendl;
}
- S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
+ S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f);
S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
- S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ;
- S32 image_buffer_y = llfloor(snapshot_height *scale_factor) ;
+ S32 image_buffer_x = llfloor(snapshot_width * scale_factor) ;
+ S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ;
- if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow
+ if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow
{
scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ;
- image_buffer_x = llfloor(snapshot_width*scale_factor) ;
- image_buffer_y = llfloor(snapshot_height *scale_factor) ;
+ image_buffer_x = llfloor(snapshot_width * scale_factor) ;
+ image_buffer_y = llfloor(snapshot_height * scale_factor) ;
}
- if(image_buffer_x > 0 && image_buffer_y > 0)
+ if ((image_buffer_x > 0) && (image_buffer_y > 0))
{
raw->resize(image_buffer_x, image_buffer_y, 3);
}
@@ -4063,7 +4057,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
{
return FALSE ;
}
- if(raw->isBufferInvalid())
+ if (raw->isBufferInvalid())
{
return FALSE ;
}
@@ -4071,6 +4065,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher
if (high_res && show_ui)
{
+ // Note: we should never get there...
llwarns << "High res UI snapshot not supported. " << llendl;
/*send_agent_pause();
//rescale fonts
@@ -4085,6 +4080,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gObjectList.generatePickList(*LLViewerCamera::getInstance());
+ // Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
+ // In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
{
S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);;
@@ -4098,69 +4095,70 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gDisplaySwapBuffers = FALSE;
gDepthDirty = TRUE;
- const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor));
-
- if (LLPipeline::sRenderDeferred)
- {
- display(do_rebuild, scale_factor, subfield, TRUE);
- }
- else
- {
- display(do_rebuild, scale_factor, subfield, TRUE);
- // Required for showing the GUI in snapshots and performing bloom composite overlay
- // Call even if show_ui is FALSE
- render_ui(scale_factor, subfield);
- }
-
S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
// handle fractional rows
U32 read_width = llmax(0, (window_width - subimage_x_offset) -
llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
- for(U32 out_y = 0; out_y < read_height ; out_y++)
+
+ // Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases)
+ if (read_width && read_height)
{
- S32 output_buffer_offset = (
- (out_y * (raw->getWidth())) // ...plus iterated y...
- + (window_width * subimage_x) // ...plus subimage start in x...
- + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
- - output_buffer_offset_x // ...minus buffer padding x...
- - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
- ) * raw->getComponents();
+ const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor));
+ display(do_rebuild, scale_factor, subfield, TRUE);
- // Ping the wathdog thread every 100 lines to keep us alive (arbitrary number, feel free to change)
- if (out_y % 100 == 0)
+ if (!LLPipeline::sRenderDeferred)
{
- LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
+ // Required for showing the GUI in snapshots and performing bloom composite overlay
+ // Call even if show_ui is FALSE
+ render_ui(scale_factor, subfield);
}
- if (type == SNAPSHOT_TYPE_COLOR)
+ for (U32 out_y = 0; out_y < read_height ; out_y++)
{
- glReadPixels(
- subimage_x_offset, out_y + subimage_y_offset,
- read_width, 1,
- GL_RGB, GL_UNSIGNED_BYTE,
- raw->getData() + output_buffer_offset
- );
- }
- else // SNAPSHOT_TYPE_DEPTH
- {
- LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
- glReadPixels(
- subimage_x_offset, out_y + subimage_y_offset,
- read_width, 1,
- GL_DEPTH_COMPONENT, GL_FLOAT,
- depth_line_buffer->getData()// current output pixel is beginning of buffer...
- );
-
- for (S32 i = 0; i < (S32)read_width; i++)
+ S32 output_buffer_offset = (
+ (out_y * (raw->getWidth())) // ...plus iterated y...
+ + (window_width * subimage_x) // ...plus subimage start in x...
+ + (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
+ - output_buffer_offset_x // ...minus buffer padding x...
+ - (output_buffer_offset_y * (raw->getWidth())) // ...minus buffer padding y...
+ ) * raw->getComponents();
+
+ // Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change)
+ if (out_y % 100 == 0)
{
- F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
-
- F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
- U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
- //write converted scanline out to result image
- for(S32 j = 0; j < raw->getComponents(); j++)
+ LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
+ }
+
+ if (type == SNAPSHOT_TYPE_COLOR)
+ {
+ glReadPixels(
+ subimage_x_offset, out_y + subimage_y_offset,
+ read_width, 1,
+ GL_RGB, GL_UNSIGNED_BYTE,
+ raw->getData() + output_buffer_offset
+ );
+ }
+ else // SNAPSHOT_TYPE_DEPTH
+ {
+ LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
+ glReadPixels(
+ subimage_x_offset, out_y + subimage_y_offset,
+ read_width, 1,
+ GL_DEPTH_COMPONENT, GL_FLOAT,
+ depth_line_buffer->getData()// current output pixel is beginning of buffer...
+ );
+
+ for (S32 i = 0; i < (S32)read_width; i++)
{
- *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+ F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
+
+ F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
+ U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
+ // write converted scanline out to result image
+ for (S32 j = 0; j < raw->getComponents(); j++)
+ {
+ *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+ }
}
}
}
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 72a4dd7f63..a19eccf748 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -760,4 +760,21 @@
<color
name="MenuBarProjectBgColor"
reference="MdBlue" />
+
+ <!-- Generic color names (legacy) -->
+ <color
+ name="white"
+ value="1 1 1 1"/>
+ <color
+ name="black"
+ value="0 0 0 1"/>
+ <color
+ name="red"
+ value="1 0 0 1"/>
+ <color
+ name="green"
+ value="0 1 0 1"/>
+ <color
+ name="blue"
+ value="0 0 1 1"/>
</colors>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 318bc9251f..3fb3717e68 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7214,7 +7214,49 @@ The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;
yestext="Quit"
notext="Don't Quit"/>
</notification>
-
+
+ <notification
+ name="NoInventory"
+ label=""
+ type="alertmodal"
+ unique="true">
+ <tag>fail</tag>
+ <tag>confirm</tag>
+ Viewing inventory is only available in Advanced mode. Would you like to logout and change modes?
+ <usetemplate
+ name="okcancelbuttons"
+ yestext="Quit"
+ notext="Don't Quit"/>
+ </notification>
+
+ <notification
+ name="NoAppearance"
+ label=""
+ type="alertmodal"
+ unique="true">
+ <tag>fail</tag>
+ <tag>confirm</tag>
+ The appearance editor is only available in Advanced mode. Would you like to logout and change modes?
+ <usetemplate
+ name="okcancelbuttons"
+ yestext="Quit"
+ notext="Don't Quit"/>
+ </notification>
+
+ <notification
+ name="NoSearch"
+ label=""
+ type="alertmodal"
+ unique="true">
+ <tag>fail</tag>
+ <tag>confirm</tag>
+ Search is only available in Advanced mode. Would you like to logout and change modes?
+ <usetemplate
+ name="okcancelbuttons"
+ yestext="Quit"
+ notext="Don't Quit"/>
+ </notification>
+
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
</global>
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index a92cc886e7..c8882fd02c 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -5,121 +5,121 @@
bg_opaque_color="DkGray"
chrome="true"
follows="left|bottom|right"
- focus_root="true"
+ focus_root="true"
height="33"
layout="topleft"
left="0"
name="bottom_tray"
top="28"
width="1310">
- <string
+ <string
name="DragIndicationImageName"
value="Accordion_ArrowOpened_Off" />
- <string
+ <string
name="SpeakBtnToolTip"
value="Turns microphone on/off" />
- <string
+ <string
name="VoiceControlBtnToolTip"
value="Shows/hides voice control panel" />
- <layout_stack
+ <layout_stack
border_size="0"
clip="false"
follows="all"
height="28"
- layout="topleft"
- left="0"
+ layout="topleft"
+ left="0"
mouse_opaque="false"
name="toolbar_stack"
orientation="horizontal"
top="0"
width="1310">
- <layout_panel
+ <layout_panel
auto_resize="false"
- user_resize="false"
+ user_resize="false"
min_width="2"
width="2" />
- <layout_panel
+ <layout_panel
auto_resize="false"
layout="topleft"
max_width="320"
min_width="214"
- height="28"
+ height="28"
mouse_opaque="false"
- name="chat_bar_layout_panel"
+ name="chat_bar_layout_panel"
user_resize="true"
- width="310" >
- <panel
- name="chat_bar"
- filename="panel_nearby_chat_bar.xml"
- left="0"
- height="28"
- width="308"
- top="0"
- mouse_opaque="false"
- follows="left|right"
+ width="310" >
+ <panel
+ name="chat_bar"
+ filename="panel_nearby_chat_bar.xml"
+ left="0"
+ height="28"
+ width="308"
+ top="0"
+ mouse_opaque="false"
+ follows="left|right"
/>
- </layout_panel>
- <!--
+ </layout_panel>
+ <!--
This 5px Panel is an indicator of where the resize handle is.
The panel provides a gap between the resize handle icon and a button to the right.
-->
- <layout_panel
- auto_resize="false"
- layout="topleft"
- max_width="5"
- min_width="5"
- name="chat_bar_resize_handle_panel"
- user_resize="false"
- width="5">
- <icon
- follows="top|right"
- height="25"
- image_name="ChatBarHandle"
- layout="topleft"
- left="-7"
- name="resize_handle"
- top="4"
- width="5" />
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="left|right"
- height="28"
- layout="topleft"
- min_height="28"
- min_width="59"
- mouse_opaque="false"
- name="speak_panel"
- top_delta="0"
- user_resize="false"
- width="108">
- <talk_button
- follows="left|right"
- height="23"
- layout="topleft"
- left="0"
- name="talk"
- top="5"
- width="105">
- <show_button
- tab_stop="true">
- <init_callback
- function="Button.SetDockableFloaterToggle"
- parameter="voice_controls" />
- </show_button>
- <!-- do not remove halign attribute with default value. otherwise it can't be overridden in other locales.
+ <layout_panel
+ auto_resize="false"
+ layout="topleft"
+ max_width="5"
+ min_width="5"
+ name="chat_bar_resize_handle_panel"
+ user_resize="false"
+ width="5">
+ <icon
+ follows="top|right"
+ height="25"
+ image_name="ChatBarHandle"
+ layout="topleft"
+ left="-7"
+ name="resize_handle"
+ top="4"
+ width="5" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="59"
+ mouse_opaque="false"
+ name="speak_panel"
+ top_delta="0"
+ user_resize="false"
+ width="108">
+ <talk_button
+ follows="left|right"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="talk"
+ top="5"
+ width="105">
+ <show_button
+ tab_stop="true">
+ <init_callback
+ function="Button.SetDockableFloaterToggle"
+ parameter="voice_controls" />
+ </show_button>
+ <!-- do not remove halign attribute with default value. otherwise it can't be overridden in other locales.
& pad_right is default value for long label which can be right aligned. See EXT-6318 -->
- <speak_button
- halign="center"
- label="Speak"
- label_selected="Speak"
- name="speak_btn"
- pad_right="20"
- tab_stop="true"
- use_ellipses="true" />
- </talk_button>
- </layout_panel>
- <layout_panel
+ <speak_button
+ halign="center"
+ label="Speak"
+ label_selected="Speak"
+ name="speak_btn"
+ pad_right="20"
+ tab_stop="true"
+ use_ellipses="true" />
+ </talk_button>
+ </layout_panel>
+ <layout_panel
auto_resize="false"
follows="right"
height="28"
@@ -131,7 +131,7 @@
top_delta="0"
user_resize="false"
width="85">
- <gesture_combo_list
+ <gesture_combo_list
follows="left|right"
height="23"
label="Gesture"
@@ -141,46 +141,46 @@
tool_tip="Shows/hides gestures"
top="5"
width="82">
- <combo_button
+ <combo_button
pad_right="10"
use_ellipses="true" />
- <combo_list
+ <combo_list
page_lines="17" />
- </gesture_combo_list>
- </layout_panel>
- <layout_panel
+ </gesture_combo_list>
+ </layout_panel>
+ <layout_panel
auto_resize="false"
- follows="right"
- height="28"
- layout="topleft"
- min_height="28"
- min_width="52"
- mouse_opaque="false"
- name="movement_panel"
- user_resize="false"
- width="83">
- <bottomtray_button
- follows="left|right"
- height="23"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Move"
- layout="topleft"
- name="movement_btn"
- tool_tip="Shows/hides movement controls"
- top="5"
- use_ellipses="true"
- width="80">
- <init_callback
- function="Button.SetDockableFloaterToggle"
- parameter="moveview" />
- </bottomtray_button>
+ follows="right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="52"
+ mouse_opaque="false"
+ name="movement_panel"
+ user_resize="false"
+ width="83">
+ <bottomtray_button
+ follows="left|right"
+ height="23"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Move"
+ layout="topleft"
+ name="movement_btn"
+ tool_tip="Shows/hides movement controls"
+ top="5"
+ use_ellipses="true"
+ width="80">
+ <init_callback
+ function="Button.SetDockableFloaterToggle"
+ parameter="moveview" />
+ </bottomtray_button>
- </layout_panel>
- <layout_panel
- auto_resize="false"
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
follows="left|right"
height="28"
layout="topleft"
@@ -190,7 +190,7 @@
name="cam_panel"
user_resize="false"
width="83">
- <bottomtray_button
+ <bottomtray_button
follows="left|right"
height="23"
image_pressed="PushButton_Press"
@@ -205,180 +205,180 @@
top="5"
use_ellipses="true"
width="80">
- <init_callback
+ <init_callback
function="Button.SetDockableFloaterToggle"
parameter="camera" />
- </bottomtray_button>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="left|right"
- height="28"
- layout="topleft"
- min_width="40"
- mouse_opaque="false"
- name="snapshot_panel"
- user_resize="false"
- width="39">
- <bottomtray_button
- follows="left|right"
- height="23"
- image_overlay="Snapshot_Off"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- layout="topleft"
- left="0"
- name="snapshots"
- tool_tip="Take snapshot"
- top="5"
- width="36">
- <init_callback
- function="Button.SetFloaterToggle"
- parameter="snapshot" />
- </bottomtray_button>
- </layout_panel>
- <layout_panel
+ </bottomtray_button>
+ </layout_panel>
+ <layout_panel
auto_resize="false"
follows="left|right"
height="28"
layout="topleft"
- min_height="28"
- min_width="52"
- mouse_opaque="false"
- name="build_btn_panel"
- user_resize="false"
- width="83">
-<!--*FIX: Build Floater is not opened with default registration. Will be fixed soon.
+ min_width="40"
+ mouse_opaque="false"
+ name="snapshot_panel"
+ user_resize="false"
+ width="39">
+ <bottomtray_button
+ follows="left|right"
+ height="23"
+ image_overlay="Snapshot_Off"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ layout="topleft"
+ left="0"
+ name="snapshots"
+ tool_tip="Take snapshot"
+ top="5"
+ width="36">
+ <init_callback
+ function="Button.SetFloaterToggle"
+ parameter="snapshot" />
+ </bottomtray_button>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="52"
+ mouse_opaque="false"
+ name="build_btn_panel"
+ user_resize="false"
+ width="83">
+ <!--*FIX: Build Floater is not opened with default registration. Will be fixed soon.
Disabled for now.
-->
- <bottomtray_button
- follows="left|right"
- height="23"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Build"
- layout="topleft"
- left="0"
- name="build_btn"
- tool_tip="Shows/hides Build Tools"
- top="5"
- use_ellipses="true"
- width="80">
- <commit_callback
- function="Build.Toggle"
- parameter="build" />
- </bottomtray_button>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="left|right"
- height="28"
- layout="topleft"
- min_height="28"
- min_width="52"
- mouse_opaque="false"
- name="search_btn_panel"
- user_resize="false"
- width="83">
- <bottomtray_button
- follows="left|right"
- height="23"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Search"
- layout="topleft"
- left="0"
- name="search_btn"
- tool_tip="Shows/hides Search"
- top="5"
- use_ellipses="true"
- width="80">
- <init_callback
- function="Button.SetFloaterToggle"
- parameter="search" />
- </bottomtray_button>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="left|right"
- height="28"
- layout="topleft"
+ <bottomtray_button
+ follows="left|right"
+ height="23"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Build"
+ layout="topleft"
+ left="0"
+ name="build_btn"
+ tool_tip="Shows/hides Build Tools"
+ top="5"
+ use_ellipses="true"
+ width="80">
+ <commit_callback
+ function="Build.Toggle"
+ parameter="build" />
+ </bottomtray_button>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|right"
+ height="28"
+ layout="topleft"
min_height="28"
- min_width="52"
+ min_width="52"
mouse_opaque="false"
- name="world_map_btn_panel"
+ name="search_btn_panel"
user_resize="false"
- width="83">
- <bottomtray_button
- follows="left|right"
- height="23"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Map"
- layout="topleft"
- left="0"
- name="world_map_btn"
- tool_tip="Shows/hides World Map"
- top="5"
- use_ellipses="true"
- width="80">
- <init_callback
- function="Button.SetFloaterToggle"
- parameter="world_map" />
- </bottomtray_button>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- follows="left|right"
- height="28"
- layout="topleft"
- min_height="28"
- min_width="52"
- mouse_opaque="false"
- name="mini_map_btn_panel"
- user_resize="false"
- width="83">
- <bottomtray_button
- follows="left|right"
- height="23"
- image_pressed="PushButton_Press"
- image_pressed_selected="PushButton_Selected_Press"
- image_selected="PushButton_Selected_Press"
- is_toggle="true"
- label="Mini-Map"
- layout="topleft"
- left="0"
- name="mini_map_btn"
- tool_tip="Shows/hides Mini-Map"
- top="5"
- use_ellipses="true"
- width="80">
- <init_callback
- function="Button.SetFloaterToggle"
- parameter="mini_map" />
- </bottomtray_button>
- </layout_panel>
- <layout_panel
- follows="left|right"
- height="30"
- layout="topleft"
- min_width="95"
- mouse_opaque="false"
- name="chiclet_list_panel"
- top="0"
- user_resize="false"
- width="189">
-<!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same
+ width="83">
+ <bottomtray_button
+ follows="left|right"
+ height="23"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Search"
+ layout="topleft"
+ left="0"
+ name="search_btn"
+ tool_tip="Shows/hides Search"
+ top="5"
+ use_ellipses="true"
+ width="80">
+ <init_callback
+ function="Button.SetFloaterToggle"
+ parameter="search" />
+ </bottomtray_button>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="52"
+ mouse_opaque="false"
+ name="world_map_btn_panel"
+ user_resize="false"
+ width="83">
+ <bottomtray_button
+ follows="left|right"
+ height="23"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Map"
+ layout="topleft"
+ left="0"
+ name="world_map_btn"
+ tool_tip="Shows/hides World Map"
+ top="5"
+ use_ellipses="true"
+ width="80">
+ <init_callback
+ function="Button.SetFloaterToggle"
+ parameter="world_map" />
+ </bottomtray_button>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="left|right"
+ height="28"
+ layout="topleft"
+ min_height="28"
+ min_width="52"
+ mouse_opaque="false"
+ name="mini_map_btn_panel"
+ user_resize="false"
+ width="83">
+ <bottomtray_button
+ follows="left|right"
+ height="23"
+ image_pressed="PushButton_Press"
+ image_pressed_selected="PushButton_Selected_Press"
+ image_selected="PushButton_Selected_Press"
+ is_toggle="true"
+ label="Mini-Map"
+ layout="topleft"
+ left="0"
+ name="mini_map_btn"
+ tool_tip="Shows/hides Mini-Map"
+ top="5"
+ use_ellipses="true"
+ width="80">
+ <init_callback
+ function="Button.SetFloaterToggle"
+ parameter="mini_map" />
+ </bottomtray_button>
+ </layout_panel>
+ <layout_panel
+ follows="left|right"
+ height="30"
+ layout="topleft"
+ min_width="95"
+ mouse_opaque="false"
+ name="chiclet_list_panel"
+ top="0"
+ user_resize="false"
+ width="189">
+ <!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same
as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. EXT-991-->
- <chiclet_panel
+ <chiclet_panel
chiclet_padding="4"
follows="left|right"
height="24"
@@ -389,7 +389,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
name="chiclet_list"
top="7"
width="189">
- <button
+ <button
auto_resize="true"
follows="right"
height="29"
@@ -406,7 +406,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
top="-28"
visible="false"
width="7" />
- <button
+ <button
auto_resize="true"
follows="right"
height="29"
@@ -423,13 +423,13 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
top="-28"
visible="false"
width="7" />
- </chiclet_panel>
- </layout_panel>
- <layout_panel auto_resize="false"
- user_resize="false"
+ </chiclet_panel>
+ </layout_panel>
+ <layout_panel auto_resize="false"
+ user_resize="false"
width="4"
min_width="4"/>
- <layout_panel
+ <layout_panel
auto_resize="false"
follows="right"
height="28"
@@ -440,7 +440,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
top="0"
user_resize="false"
width="37">
- <chiclet_im_well
+ <chiclet_im_well
follows="right"
height="28"
layout="topleft"
@@ -449,7 +449,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.
name="im_well"
top="0"
width="35">
- <!--
+ <!--
Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button
xml attribute Description
image_unselected "Unlit" - there are no new messages
@@ -457,7 +457,7 @@ image_selected "Unlit" + "Selected" - there are no new messages and the
image_pressed "Lit" - there are new messages
image_pressed_selected "Lit" + "Selected" - there are new messages and the Well is open
-->
- <button
+ <button
auto_resize="true"
follows="right"
halign="center"
@@ -472,13 +472,13 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
name="Unread IM messages"
tool_tip="Conversations"
width="34">
- <init_callback
+ <init_callback
function="Button.SetDockableFloaterToggle"
parameter="im_well_window" />
- </button>
- </chiclet_im_well>
- </layout_panel>
- <layout_panel
+ </button>
+ </chiclet_im_well>
+ </layout_panel>
+ <layout_panel
auto_resize="false"
follows="right"
height="28"
@@ -489,7 +489,7 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
top="0"
user_resize="false"
width="37">
- <chiclet_notification
+ <chiclet_notification
follows="right"
height="23"
layout="topleft"
@@ -498,7 +498,7 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
name="notification_well"
top="5"
width="35">
- <button
+ <button
auto_resize="true"
bottom_pad="3"
follows="right"
@@ -514,17 +514,17 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well
name="Unread"
tool_tip="Notifications"
width="34">
- <init_callback
+ <init_callback
function="Button.SetDockableFloaterToggle"
parameter="notification_well_window" />
- </button>
- </chiclet_notification>
- </layout_panel>
- <layout_panel
- auto_resize="false"
- user_resize="false"
- min_width="4"
- name="DUMMY2"
- width="8" />
- </layout_stack>
+ </button>
+ </chiclet_notification>
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ user_resize="false"
+ min_width="4"
+ name="DUMMY2"
+ width="8" />
+ </layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
index 6040d24128..ea1d89c975 100644
--- a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
+++ b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml
@@ -3,6 +3,20 @@
follows="left|top"
mouse_opaque="false"
name="loading_indicator"
- rotations_per_sec="1.0"
- tab_stop="false"
-/>
+ images_per_sec="1.0"
+ tab_stop="false">
+ <images>
+ <image name="Progress_1"/>
+ <image name="Progress_2"/>
+ <image name="Progress_3"/>
+ <image name="Progress_4"/>
+ <image name="Progress_5"/>
+ <image name="Progress_6"/>
+ <image name="Progress_7"/>
+ <image name="Progress_8"/>
+ <image name="Progress_9"/>
+ <image name="Progress_10"/>
+ <image name="Progress_11"/>
+ <image name="Progress_12"/>
+ </images>
+</loading_indicator> \ No newline at end of file
diff --git a/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml b/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml
index d0a77e8c2a..e0c0bd13d9 100644
--- a/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml
@@ -59,8 +59,8 @@
follows="left|right"
/>
</layout_panel>
- <layout_panel
- auto_resize="false"
+ <layout_panel
+ auto_resize="false"
follows="right"
height="28"
layout="topleft"
@@ -163,7 +163,7 @@
layout="topleft"
left="0"
name="destination_btn"
- tool_tip="Shows destinations"
+ tool_tip="Shows destinations window"
top="5"
is_toggle="true"
use_ellipses="true"
diff --git a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml
index 53def54aca..c3f46f11e0 100644
--- a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml
+++ b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml
@@ -23,5 +23,69 @@
orientation="vertical"
top_pad="5"
width="145">
+ <layout_panel
+ auto_resize="false"
+ follows="top|left|right"
+ height="20"
+ layout="topleft"
+ left="2"
+ min_height="20"
+ width="140"
+ name="view_profile_btn_panel"
+ top="0"
+ user_resize="false">
+ <button
+ follows="left|top|right"
+ height="23"
+ label="Profile"
+ name="view_profile_btn"
+ top="0"
+ width="140" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="top|left|right"
+ height="25"
+ layout="topleft"
+ min_height="25"
+ width="140"
+ name="add_friend_btn_panel"
+ user_resize="false">
+ <button
+ follows="left|top|right"
+ height="23"
+ label="Add Friend"
+ name="add_friend_btn"
+ top="5"
+ width="140" />
+ </layout_panel>
+ <layout_panel
+ auto_resize="false"
+ follows="top|left|right"
+ height="25"
+ layout="topleft"
+ min_height="25"
+ width="140"
+ name="teleport_btn_panel"
+ user_resize="false">
+ <button
+ auto_resize="false"
+ follows="left|top|right"
+ height="23"
+ label="Teleport"
+ name="teleport_btn"
+ tool_tip = "Offer to teleport this person"
+ width="140" />
+ </layout_panel>
+ <layout_panel
+ mouse_opaque="false"
+ auto_resize="true"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ min_height="0"
+ width="140"
+ name="spacer"
+ user_resize="false" />
</layout_stack>
</panel>
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 7164934b26..884b00f0cc 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -2154,6 +2154,10 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e
}
break;
+ case MEDIA_EVENT_NAVIGATE_ERROR_PAGE:
+ std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl;
+ break;
+
case MEDIA_EVENT_CLICK_LINK_HREF:
{
std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl;