Wrench value from your Creo Investments Home Measure the benefits Simple Automation can bring Why
Automate?
A personal way to do PDM Peer to Peer
PDM
3D Drawings Model Based
Design
Smooth out unwanted sharp edges Other
Articles
www.proetoolbox.co.uk - Simple Automation made Simple

Creating Self Optimising Functions

Due to differences in the implementations of Pro/Web.Link between UNIX and Windows platforms, PTC recommends that Pro/Web.Link object handling code is handled with a custom function. In this article we see how the function works and write a different one that automatically re-writes itself based on the platform the application is being run on.

function pfcIsIE ()
{
  //IE8,9,10
  if (navigator.appName.indexOf ("Microsoft") != -1)
  { 
    return true;
  }
  else
  {
    //IE11
    if (navigator.userAgent.indexOf("Trident")!=-1)
    {
      return true;
    }
    else
    {
      return false;
    }
  }
}

function pfcCreate (className)
{
  if (!pfcIsIE())
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

  if (pfcIsIE())
    return new ActiveXObject ("pfc."+className);
  else
  {
    ret = Components.classes ["@ptc.com/pfc/" + 
      className + ";1"].createInstance();
    return ret;
  }
}

The Conventional Method

In the example code (shown right) you can see that pfcIsIE() evaluates the property of the browser in order to figure out if the browser is Internet Explorer or not. Also pfcCreate() is calling pfcIsIE() and returning an appropriate object for Pro/Web.Link code to work with. All of this is completely logical as one would expect. Using these functions allows the application writer to write code that can be used on either platform with [hopefully] no issues.

function pfcIsWindows ()
{//IE8,9,10
  if (navigator.appName.indexOf ("Microsoft") != -1)
  {
    pfcIsIE = function(){return true;};
  }
  else
  {
    if (navigator.userAgent.indexOf("Trident")!=-1)
    {//IE11
      pfcIsIE = function(){return true;};
    }
    else
    {
      pfcIsIE = function(){return false;};
    }
  }
  return pfcIsIE();
}

function pfcCreate (className)
{
  if (!pfcIsIE())
  {
    pfcCreate = function(className){
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        ret = Components.classes ["@ptc.com/pfc/" + 
          className + ";1"].createInstance();
        return ret;
     };
  }
  else
  {
    pfcCreate = function(className){
        return new ActiveXObject ("pfc."+className);
     };
  }
  return pfcCreate(className);
}


Writing Self-Optimising Functions

The problem with NOT having platform specific code is that, for applications that call these functions repeatedly, each evaluation takes processing time. While it's never been a big performance hit for me, I love the fact that JavaScript is so malleable that it can even re-write it's own functions at run time to improve performance whilst still maintaining flexibility.

Notice how the code right has lines in it such as 'pfcIsWindows = function(' and 'pfcCreate = function('. These statements are actually re-writing the function such that it's content is now devoid of any evaluations and instead returns exactly what's needed for the platform in question.

Conclusion

JavaScript is a truly flexible language, being able to write self-optimising functions is very remarkable and for applications that process hundreds of thousands of calls to pfcCreate the performance improvement is nice to have.