logo WinWrap®

COM: Script Caching

COM: Script Caching

  • Manage script lifetimes
  • BasicIdeCtl synchronized with a BasicNoUIObj in the same thread
  • Application evaluates function defined by script
  • DesignMode controls script editing/evaluation for the application
  • COM Sample Implementation

COM: Script Caching

For an explanation of how this sample works please refer to the Script Caching solution.

Sample source: ScriptCaching-Com.zip

COM: Script Caching

Load a script:

HRESULT ScriptManager::LoadScript(const wchar_t* script_name, ScriptNode*& script_node) { std::wstring name = script_name; if (name[0] != L'\\') { // relative script path if (!active_script_node_) name = L"\\" + name; else { bstr_t namex(name.c_str()); Combine(bstr_t(active_script_node_->ScriptName().c_str()), bstr_t(name.c_str()), &namex.GetBSTR()); name = namex; } } script_node = 0; // is the script already loaded auto it = std::find_if(loaded_script_nodes_.begin(), loaded_script_nodes_.end(), [&name](auto script_nodex) { return script_nodex->ScriptName() == name; }); if (it != loaded_script_nodes_.end()) script_node = *it; if (!script_node) // not active or loaded script_node = new ScriptNode(name.c_str()); // evaluate a script node if (!script_node->IsLoaded()) { // load the script, a syntax error will return a failed hr HRESULT hr = script_node->Load(basicNoUIObj_, fast_); if (FAILED(hr)) return hr; // syntax error // add to front of the loaded list loaded_script_nodes_.push_front(script_node); // update tree view with new status script_loaded_status_changed_(script_node->ScriptName(), true); while (loaded_script_nodes_.size() > max_loaded_scripts) { // remove the back (oldest loaded script node) auto oldest_script_node = loaded_script_nodes_.back(); if (oldest_script_node->IsActive()) break; loaded_script_nodes_.pop_back(); oldest_script_node->Unload(); // update tree view with new status script_loaded_status_changed_(oldest_script_node->ScriptName(), false); } } else if (script_node != loaded_script_nodes_.front()) { // move to the front of the loaded list loaded_script_nodes_.remove(script_node); loaded_script_nodes_.push_front(script_node); } return S_OK; }
Evaluate a script:
HRESULT ScriptManager::EvaluateScript(ScriptNode* script_node, VARIANT& result, const VARIANT* default_value) { // script is active ScriptNode* previous_active_script_node = active_script_node_; active_script_node_ = script_node; // a run-time error will be return failed hr HRESULT hr = script_node->Evaluate(result, default_value); // script is no longer active active_script_node_ = previous_active_script_node; return hr; }
Sample script:
'#Language "WWB-COM" Option Explicitwwbnet Function Action3() As Variant Return "Item3\Action3: " & LoadScript("\Item4\Action1.bas").Evaluate End Function
Sample script:
'#Language "WWB-COM" Option Explicit Function Action1() As Variant ' measure Evaluate performance Dim script As Script Set script = LoadScript("Nop.bas") Const count = 1000000 Dim t0 As Single t0 = Timer Dim i As Long For i = 1 To count script.Evaluate Next Dim t1 As Single t1 = Timer Return "Item4\Timer\Action1: " & Int(count/(t1-t0)) & " per second" End Function

Copyright Polar Engineering, Inc.