From 27909ac8353f57fb9a08c70a692fd182b56edd43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20=E2=80=98Touky=E2=80=99=20Huet?= Date: Thu, 26 Sep 2013 18:20:24 +0000 Subject: [PATCH] MeshViewer : Html split in .js so other NaCl version should be easier. Added crash/error handling with restart. Added Best match sorting in command listing. --- test/TypeDictionnary.js | 205 +++++++++- ...ictionnary.js => easy_mesh_dictionnary.js} | 0 test/meshviewer.vcxproj | 11 +- test/meshviewer_index.html | 386 +++++------------- test/nacl_loading.js | 211 ++++++++++ 5 files changed, 519 insertions(+), 294 deletions(-) rename test/{EasyMeshDictionnary.js => easy_mesh_dictionnary.js} (100%) create mode 100644 test/nacl_loading.js diff --git a/test/TypeDictionnary.js b/test/TypeDictionnary.js index 54177d00..d887191f 100644 --- a/test/TypeDictionnary.js +++ b/test/TypeDictionnary.js @@ -11,7 +11,7 @@ function TypeDictionnary(m_name) function CmdVarObj() { } function CmdVar(m_type, m_syntax) { - var current_mesh_dict = GetCmdDictionnary(); + var current_dict = GetCmdDictionnary(); new_obj = new CmdVarObj(); new_obj.m_type = m_type; new_obj.m_syntax = m_syntax; @@ -22,7 +22,7 @@ function CmdVar(m_type, m_syntax) for (var i = 0; i < m_syntax.length; i++) res += m_syntax[i] + ' '; } - current_mesh_dict.m_vars[current_mesh_dict.m_vars.length] = new_obj; + current_dict.m_vars[current_dict.m_vars.length] = new_obj; } //----------------------------------------------------------------------------- @@ -50,7 +50,7 @@ function CmdArg(m_type, m_name, m_optional) function CmdTypeObj() { } function CmdType(m_name, m_comment, m_arg) { - var current_mesh_dict = GetCmdDictionnary(); + var current_dict = GetCmdDictionnary(); new_obj = new CmdTypeObj(); new_obj.m_name = m_name; new_obj.m_comment = m_comment; @@ -95,7 +95,7 @@ function CmdType(m_name, m_comment, m_arg) } return false; } - current_mesh_dict.m_cmds[current_mesh_dict.m_cmds.length] = new_obj; + current_dict.m_cmds[current_dict.m_cmds.length] = new_obj; } //----------------------------------------------------------------------------- @@ -105,7 +105,7 @@ function FindMatchingCommand(src_text_area) { if (src_text_area != undefined) { - var current_mesh_dict = GetCmdDictionnary(); + var current_dict = GetCmdDictionnary(); var found_match = ""; var check = true; var cursor = Math.min(src_text_area.selectionStart, src_text_area.value.length - 1); @@ -149,10 +149,201 @@ function FindMatchingCommand(src_text_area) var match_data = new Object(); match_data.match = found_match; match_data.match_list = new Array(); - for (cursor = 0; cursor < current_mesh_dict.m_cmds.length; cursor++) - if (current_mesh_dict.m_cmds[cursor].CheckCommand(found_match)) + for (cursor = 0; cursor < current_dict.m_cmds.length; cursor++) + if (current_dict.m_cmds[cursor].CheckCommand(found_match)) match_data.match_list[match_data.match_list.length] = cursor; return match_data; } } + +//----------------------------------------------------------------------------- +//Build a TOC from all commands first letter +//----------------------------------------------------------------------------- +function BuildTOC(with_dot) +{ + var res = ''; + var current_dict = GetCmdDictionnary(); + for (var a = 'a'.charCodeAt(0); a <= 'z'.charCodeAt(0); a++) + { + var stop = false; + for (var i = 0; !stop && i < current_dict.m_cmds.length; i++) + { + for (var j = 0; j < current_dict.m_cmds[i].m_name.length; j++) + { + if (current_dict.m_cmds[i].m_name[j][0] == String.fromCharCode(a)) + { + res += String.fromCharCode(a); + stop = true; + break; + } + } + } + if (!stop && with_dot) + res += '.'; + } + return res; +} + +//----------------------------------------------------------------------------- +//Setup code lookup logic +//----------------------------------------------------------------------------- +function CmdLookup(div_cmds, div_args, div_cmnt, div_vars, text_src) +{ + var cur_dict = GetCmdDictionnary(); + if (text_src != undefined) + { + var cmd_size = 8; + var found = FindMatchingCommand(text_src); + if (found.match_list.length > 0) + { + var perfect_match = false; + var best_match = 0; + var best_length = 300000; + //Find the best match to put it in first in the list + for (var i = 0; i < found.match_list.length && best_length > 0; i++) + { + var cur_match = cur_dict.m_cmds[found.match_list[i]]; + for (var j = 0; j < cur_match.m_name.length && best_length > 0; j++) + { + if (cur_match.m_name[j].length == found.match.length) + { + perfect_match = true; + best_match = i; + best_length = 0; + } + else if (cur_match.m_name[j].length < best_length && + cur_match.m_name[j].length > found.match.length) + { + best_match = i; + best_length = cur_match.m_name[j].length; + } + } + } + var tmp = found.match_list[0]; + found.match_list[0] = found.match_list[best_match]; + found.match_list[best_match] = tmp; + + var type_list = new Array(); + div_cmds[0].innerHTML = ""; + div_cmds[1].innerHTML = ""; + div_args.innerHTML = ""; + div_cmnt.innerHTML = ""; + //Go through the found matches and show them. + for (var i = 0; i < found.match_list.length; i++) + { + var cur_match = cur_dict.m_cmds[found.match_list[i]]; + div_cmds[0].innerHTML += '['; + var max = cur_match.m_name.length; + var word = 0; + for (var j = 0; j < max; j++) + { + var mth = found.match; + var cmd = cur_match.m_name[j]; + //Matching start caracters should be bold + if (mth == cmd.slice(0, mth.length)) + { + div_cmds[word].innerHTML += ' '; + div_cmds[word].innerHTML += '' + mth + ''; + div_cmds[word].innerHTML += cmd.slice(mth.length, cmd.length); + word++; + } + } + //Complete empty command by
so commands in the two columns are on the same line + word = (word > 0)?(2):(0); + while (word-- > 0) + div_cmds[word].innerHTML += "
"; + //Go through the arguments and show them, force if we found the perfect match + if (perfect_match || (found.match_list.length < 4 && i == 0)) + { + div_args.innerHTML += " > "; + if (cur_match.m_arg != undefined) + { + max = cur_match.m_arg.length; + var found_optional = false; + for (var j = 0; j < max; j++) + { + if (cur_match.m_arg[j].m_optional != undefined && found_optional == false) + { + var tab = '
'; for (var l = 0; l < 5; l++) tab += ' '; + div_args.innerHTML += tab + 'Opt: ['; + found_optional = true; + } + else if (j > 0) + div_args.innerHTML += ', '; + + //Types are bold + div_args.innerHTML += '' + cur_match.m_arg[j].m_type + ' '; + type_list[type_list.length] = cur_match.m_arg[j].m_type; + //Names are not + div_args.innerHTML += cur_match.m_arg[j].m_name; + if (cur_match.m_arg[j].m_optional != undefined) + div_args.innerHTML += ' = ' + cur_match.m_arg[j].m_optional + ''; + } + if (found_optional == true) + div_args.innerHTML += '] '; + div_args.innerHTML += ' 
'; + } + //Add the comment + if (cur_match.m_comment != undefined) + { + var tb_i = 16; var in_i = 8; + var tab = '
'; + if (cur_match.m_arg == undefined) { tb_i -= 8; in_i -= 8; } + for (var l = 0; l < in_i; l++) div_args.innerHTML += ' '; + for (var l = 0; l < tb_i; l++) tab += ' '; + div_args.innerHTML += cur_match.m_comment + ' '; + while (div_args.innerHTML.indexOf('\n') > -1) + div_args.innerHTML = div_args.innerHTML.replace('\n', tab); + } + } + } + //Go through the type list and bold the used ones. + if (cur_dict.m_vars != undefined) + { + div_vars.innerHTML = ""; + var max = cur_dict.m_vars.length; + for (var j = 0; j < max; j++) + { + var cur_var = cur_dict.m_vars[j]; + div_vars.innerHTML += " > "; + var k = 0; + for (; k < type_list.length; k++) + if (cur_var.m_type == type_list[k]) + break; + + //Bold the used variables + if (k < type_list.length) + div_vars.innerHTML += "" + cur_var.m_type + ""; + else + div_vars.innerHTML += cur_var.m_type; + + if (cur_var.m_syntax != undefined) + { + var align_size = 9; + var cmd_size = cur_var.m_type.length + 3; + for (var m = 0; m < cur_var.m_syntax.length; m++) + { + for (var l = 0; l < align_size - cmd_size; l++) + div_vars.innerHTML += " "; + div_vars.innerHTML += cur_var.m_syntax[m] + "
"; + cmd_size = 0; + } + var tab = ''; + for (var l = 0; l < align_size - cmd_size; l++) + tab += " "; + while (div_vars.innerHTML.indexOf('\n') > -1) + div_vars.innerHTML = div_vars.innerHTML.replace('\n', '
' + tab); + } + } + } + } + else + { + div_cmds[0].innerHTML = "[ ... "; + div_cmds[1].innerHTML = ""; + div_args.innerHTML = ""; + div_cmnt.innerHTML = ""; + } + } +} \ No newline at end of file diff --git a/test/EasyMeshDictionnary.js b/test/easy_mesh_dictionnary.js similarity index 100% rename from test/EasyMeshDictionnary.js rename to test/easy_mesh_dictionnary.js diff --git a/test/meshviewer.vcxproj b/test/meshviewer.vcxproj index e40c2711..635ca18b 100644 --- a/test/meshviewer.vcxproj +++ b/test/meshviewer.vcxproj @@ -60,14 +60,21 @@ true - + + true + true true - + + true + + + true + diff --git a/test/meshviewer_index.html b/test/meshviewer_index.html index c2f4a07d..38c46cb9 100644 --- a/test/meshviewer_index.html +++ b/test/meshviewer_index.html @@ -14,10 +14,6 @@ body { font:12px Consolas; } -#status_field -{ - font:12px Consolas; -} button { font:14px Consolas; @@ -26,13 +22,25 @@ textarea { font:14px Consolas; } +#id_div_progress_status +{ + font:12px Consolas; +} +#id_div_progress +{ + position: absolute; + top: 40%; + left: 30%; + right: 30%; + z-index: 3; +} progress { background-color: #f3f3f3; border: 0; height: 18px; width: 200px; - border-radius: 9px; + border-radius: 9px; } progress::-webkit-progress-bar { @@ -49,18 +57,11 @@ progress::-webkit-progress-value height: 14px; border-radius: 0px; } -#listener +#id_div_listener { position: relative; } -#progress_bar -{ - position: absolute; - top: 40%; - left: 40%; - z-index: 3; -} -#DIV_nacl_div +#id_div_embed_data { position: absolute; top: 2px; @@ -71,7 +72,7 @@ progress::-webkit-progress-value { border:1px solid #000000; } -#DIV_command0 +#id_div_helper_cmd_0 { margin-left: 5px; } @@ -79,331 +80,146 @@ progress::-webkit-progress-value Mesh Viewer NaCl + + + - +

Mesh Viewer : Native Client version.

-
+
-
-
NO-STATUS
- +
+
....
+
-
+
+
-

-
+
diff --git a/test/nacl_loading.js b/test/nacl_loading.js new file mode 100644 index 00000000..e2d06b8b --- /dev/null +++ b/test/nacl_loading.js @@ -0,0 +1,211 @@ +g_status_text = [null]; +g_status_timer = [-1.0]; +g_var_progress_bar = -1; + +window.setTimeout("RegisterListener()", 200); + +function RegisterListener() +{ + //Register all the correct functions to the listener + var div_listener = GetNaClListenerDiv(); + if (div_listener) + { + div_listener.addEventListener('loadstart', ModuleStartedLoad, true); + div_listener.addEventListener('load', ModuleDidLoad, true); + div_listener.addEventListener('error', ModuleError, true); + div_listener.addEventListener('progress', ModuleLoadUpdate, true); + div_listener.addEventListener('message', ModuleSentMessage, true); + div_listener.addEventListener('crash', ModuleCrash, true); + window.setTimeout("UpdateTextStatus()", 100); + } + else if (IsUsingNaCl()) + window.setTimeout("RegisterListener()", 200); +} + +//------------------------------------------------------------------------- +// MODULE LOADING FUNCTIONS +//------------------------------------------------------------------------- +//Indicate page has been loaded. +function PageDidLoad() +{ + //Page did load before NaCl module + if (GetNaClModuleVar() == null) + AddTextStatus('Please wait for module loading'); +} + +//Module starts load +function ModuleStartedLoad() +{ + AddTextStatus('Module Started Loading'); + InitNaClModuleVar(); +} + +//Module progress event +function ModuleLoadUpdate(event) +{ + var progress_bar = GetProgressBar(); + if (progress_bar) + { + if (event.lengthComputable) + { + if (progress_bar.value < 0) + g_var_progress_bar = -1; + var loading_text = 'Please wait, loading [' + (Math.min(1.0, event.loaded / event.total) * 100.0).toFixed(0) + '%]'; + //update the progress status. + progress_bar.max = event.total; + progress_bar.value = event.loaded; + g_var_progress_bar = AddTextStatus(loading_text, g_var_progress_bar); + } + //Load length is not usable. + else + { + progress_bar.value = -1; + g_var_progress_bar = AddTextStatus('Please wait, calculating load balance ...', g_var_progress_bar); + } + } +} + +//Indicate module load success. +function ModuleDidLoad() +{ + if (GetNaClModuleVar() == null) + InitNaClModuleVar(); + + //Hide the progress div + AddTextStatus('Module is live, thank you for your patience.'); + window.setTimeout('HideProgressStatus(true)', 4000); +} + +//Module did crash +function ModuleCrash(event) +{ + RestartModule(); + AddTextStatus("Module has crashed ! Restarting ..."); +} + +//Module had an error +function ModuleError(event) +{ + RestartModule(); + AddTextStatus("Module Load/start Error ! Restarting ..."); +} + +//Used to restart module on crash/error/load fail .... +function RestartModule() +{ + var div_embed_data = GetDivEmbedData(); + var div_embed_data_save = GetDivEmbedDataSave(); + + if (div_embed_data && div_embed_data_save) + { + HideProgressStatus(false); + + div_embed_data_save = div_embed_data.innerHTML; + div_embed_data.innerHTML = ''; + window.setTimeout('RestartModuleRestoreEmbed()', 1000); + } +} + +function RestartModuleRestoreEmbed() +{ + var div_embed_data = GetDivEmbedData(); + var div_embed_data_save = GetDivEmbedDataSave(); + + if (div_embed_data && div_embed_data_save) + { + div_embed_data.innerHTML = div_embed_data_save; + div_embed_data.innerHTML = ''; + HideProgressStatus(false); + } +} + +//------------------------------------------------------------------------- +// MODULE COMMUNICATION FUNCTIONS +//------------------------------------------------------------------------- + +//Handle message from the NaCl module +function ModuleSentMessage(message) +{ + alert('Module sent message: ' + message.data); +} + +//Called by the "Send Mesh Command !" button +function SendMessageToModule() +{ + if (GetNaClModuleVar()) + GetNaClModuleVar().postMessage(GetTextAreaCodeSrc().value); + else + alert("Module not loaded !"); +} + +//------------------------------------------------------------------------- +// PROGRESS BAR STATUS FUNCTIONS +//------------------------------------------------------------------------- + +//Update progress bar status +function UpdateTextStatus(seconds) +{ + var div_progress_status = GetDivProgressStatus(); + if (div_progress_status) + { + div_progress_status.innerHTML = ''; + for (var i = 0; i < g_status_text.length; i++) + { + if (g_status_timer[i] == undefined || g_status_timer[i] < 0.0) + { + g_status_timer[i] = -1.0; + g_status_text[i] = undefined; + } + else + { + g_status_timer[i] -= seconds; + div_progress_status.innerHTML += g_status_text[i]; + if (i < g_status_text.length - 1) + div_progress_status.innerHTML += '
'; + } + } + window.setTimeout("UpdateTextStatus()", 100); + } +} + +//Add text status to the stack +function AddTextStatus(message, message_id) +{ + if (message_id == undefined || message_id < 0) + { + g_status_text[g_status_text.length] = message; + g_status_timer[g_status_timer.length] = 5.0; + return g_status_timer.length - 1; + } + else + { + g_status_text[message_id] = message; + g_status_timer[message_id] = 5.0; + return message_id; + } +} + +//Hide Progress Status and empty status texts +function HideProgressStatus(should_hide) +{ + var progress_bar = GetProgressBar(); + var div_progress = GetDivProgress(); + if (div_progress && progress_bar) + { + if (should_hide == true) + { + div_progress.style.visibility = "hidden"; + g_status_text.splice(0, g_status_text.length); + g_status_timer.splice(0, g_status_timer.length); + progress_bar.value = -1; + UpdateTextStatus(0.1); + } + else + { + div_progress.style.visibility = "visible"; + progress_bar.value = -1; + AddTextStatus('Please wait for module loading'); + UpdateTextStatus(0.1); + } + } +}
-
 
Variable Types usage :
-
+
-
+
- - - - + + + +