I’m currently developing a URCap program that uses several global variables to keep track of the current command and state.
Everything works fine functionally but all these global variables are visible in the Variables section of PolyScope, which makes the interface look messy and could confuse the end user.
I tried using local variables, but then other functions and scripts inside the URCap cannot access them anymore.
Is there any way to hide global variables from the user interface (or make them private/internal) while still keeping them accessible to all functions within the URScript runtime?
Alternatively, is there a recommended pattern or naming convention for internal variables that should not be exposed to the user?
I also just use global variables. And I agree it’s pretty clunky, especially on the end user UI. What I think a lot of other companies use is an xmlrpc server architecture. Where instead of having the CAP write raw script, the CAP writes script calls to an xmlrpc server running on the Java side. Then you manipulate Java variables and have the script call xmlrpc methods like “getMyVariable()” and in that way you never actually see the variable in URScript. This also serves as a way of obfuscating the code a little bit. Otherwise anyone can open the script file and see exactly what you’re doing. (They can do the same with the CAP by just decompiling the jar file but…here nor there.)
Thanks a lot for your detailed answer that’s really helpful.
I hadn’t thought about using an XML-RPC approach to keep the global state on the Java side, that makes perfect sense.
Would you maybe have a small example or reference on how you structured that communication (e.g., a minimal XML-RPC setup or code snippet)?
Thanks again for taking the time to share your experience!
Best,
Halit
I don’t really, as it’s not how I implemented my main stuff. I use it only a little bit, and it was all cobbled together years ago. I didn’t know how it worked then, and can’t say I really do now either.
And then I have some class that maps the script commands to Java functions:
import java.io.IOException;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;
/*
* Sets up the XMLRPC server running in Java to handle calls made from URScript and map them
* to the apprpriate Java functions. These can be seen in the "JavaScriptHandler" class.
*/
public class ScriptToJava extends XmlRpcServer{
private WebServer webServer;
public ScriptToJava(int port) throws Exception {
webServer = new WebServer(port);
XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
PropertyHandlerMapping phm = new PropertyHandlerMapping();
phm.addHandler("myCommand", JavaScriptHandler.class);
xmlRpcServer.setHandlerMapping(phm);
XmlRpcServerConfigImpl config = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
config.setEnabledForExtensions(true);
config.setContentLengthOptional(false);
}
public void start() throws IOException {
webServer.start();
}
public void stop() {
webServer.shutdown();
}
}
And then I had the functions defined in a class like this:
public class JavaScriptHandler {
public int myCommand(double exampleInput) throws ScriptToJavaException{
myStaticJavaVariable = exampleInput;
//Do other stuff
return someValue;
}
}
And an Exception class like this:
public class ScriptToJavaException extends Exception{
private static final long serialVersionUID = 0L;
public ScriptToJavaException(String message) {
super(message);
}
}
And then you stand up an instance of the server (I did it in my Activator class):
try {
ScriptToJava myServer = new ScriptToJava(40406);
myServer.start();
System.out.println("XML_RPC server has started on port: 40406");
} catch (Exception e) {
System.out.println("XML_RPC server FAILED TO START on port: 40406");
e.printStackTrace();
}
This was all ripped from Google in one way or another. And then I had to import a bunch of stuff to the pom file, and I barely understood any of that. All of my Java is self-taught so hopefully this stuff means more to you than it does to me
Not trying to resurrect an old thread, but I just found this out:
If you name a variable _hidden_yourVariableName it is accessible but not visible in the variables tab. So the following script produces a globally scope variable that doesn’t show up in the variables tab: