= Load data in your plugins = Once you now the [wiki:PtolemyPluginCreate basics to create a plugin], here we explain how you can load data in your plugins. For convention and improvement, data can't be loaded in the rendering loop. This way if you load a big file the whole viewer will remain freeze until all data be read. The {{{Plugin}}} interface has some methods that can be used to start a new thread responsible to load your data, like: {{{tileLoaderAction}}}, {{{reloadData}}} or {{{initGL}}}. Here we present the {{{IconPlugin}}} which can draw an icon at some lat/lon position. ---- [[PageOutline(2-3,,inline)]] ---- == How to use the !IconPlugin == The {{{IconPlugin}}} requires three parameters: * Path to the image file, respect the server URL you have specified in the {{{server}}} applet parameter. * The position specified as: {{{latitude, longitude}}}. The next is an example suppousing it is the first plugin in your plugin list: {{{ #!text/html ... org.ptolemy3d.plugin.IconPlugin /some_dir/some_image.png,lat,lon ... }}} == Loading the icon image == The code for {{{IconPlugin}}} is attached to this page, please take a look before continue reading. The important thing here is show you how load data without freeze the application. For that purpose, we are using three flags: {{{ #!java private boolean iconLoaded = false; private boolean errorLoading = false; private boolean initTexture = false; }}} This flags serves us to: * iconLoaded: true if the icon was successfully loaded, * errorLoading: true if any error occurs loading the icon image, and * initTexture: true if the texture object was initialized with the icon image. In the {{{IconPlugin}}} we have selected the {{{initGL()}}} method to create a new thread where to load the data. Then, when the OpenGL context is initialized the plugin is notified and can create a new thread responsible to load the icon image from the server. Once the data is loaded the {{{iconLoaded}}} flag is set to true, otherwise, if any error occurs the {{{errorLoading}}} is set to true. {{{ #!java public void initGL(GL gl) { if (!iconLoaded) { Thread newThread = new Thread(new Runnable() { public void run() { URL url; try { String server = ptolemy.configuration.server; url = new URL("http://" + server + imageName); bufferedImage = ImageIO.read(url); } catch (IOException ex) { Logger.getLogger(IconPlugin.class.getName()).log(Level.SEVERE, null, ex); errorLoading = true; } finally { iconLoaded = true; } } }); newThread.start(); } } }}} == Drawing the icon image == Now, take a look at {{{draw()}}} method. This method is called inside the rendering loop. We can't make any expensive-in-time action. The load process, which is expensive, is made in the {{{initGL()}}} method. Here we: * check the lat/lon point are going to draw is in the visible side of the globe, * check the icon is loaded or no error occurs, and finally * check the texture object was initialized, if not, then initialize it and set the flag { {{initTexture}}} to true. {{{ #!java public void draw(GL gl) { // Check if our point is in the visible side of the globe. if (!isPointInView(longitude, latitude)) { return; } // If the icon image is not loaded return or there was an error loading // it then returns. if (!iconLoaded || errorLoading) { return; } // Initiallize the texture if (!initTexture) { initTexture = true; texture = TextureIO.newTexture(bufferedImage, false); } ... ... } }}} [[Image(iconplugin.jpg)]] == Special considerations == Remember to be careful when implementing the {{{draw()}}} method. We encourage to make this steps for all your plugins: * store the current projection and modelview matrices, * store any OpenGL attribute you are going to change: line size, blend function, ... * draw your geometries, modifying the matrices or attribute, * restore the attributes, * restore the the matrices.