Ken Webb 2011-01-27T14:13:25Z
The Bestiary sample web app currently uses PulpCore graphics. Using the scripts on this page, the Bestiary web app can also use the HTML5 Canvas.
The first script is a HTML5 Canvas server. It's written in JavaScript and runs in a web browser such as Firefox. Copy the script from this wiki page, and paste it into the console in the Bestiary app. Then press the submit button.
<script implName="lang:BrowserJS:inline:"><![CDATA[ var drawScene_Function = "\ <script type='text/javascript'>\ /*\ * drawScene(context, dataFromClient)\ * id: 10=Cat 11=Human 3=Dog 4=Zombie 5=Termite\ * example of data: id,x,y\ * 1,13,20|\ * 1,16,31|\ * 2,17,15|\ * 3,17,16|\ * 1,17,21\ */\ function drawScene(ctx, theData) {\ ctx.fillStyle = 'green';\ ctx.fillRect(0, 0, 499, 499);\ var rowItems = theData.split('|');\ for (i in rowItems) {\ var colItems = rowItems[i].split(',');\ if (colItems.length != 3) {continue;}\ var id = colItems[0];\ var x = colItems[1] * 5;\ var y = colItems[2] * 5;\ /* customized for Bestiary */\ switch (id) {\ case '11': ctx.fillStyle = 'tan'; break;\ case '10': ctx.fillStyle = 'lightgrey'; break;\ case '3': ctx.fillStyle = 'white'; break;\ case '4': ctx.fillStyle = 'pink'; break;\ case '5': ctx.fillStyle = 'yellow'; break;\ default: ctx.fillStyle = 'magenta'; break;\ }\ ctx.fillRect(x, y, 5, 5);\ }\ };\ </script>"; $('div#divHeadOne').html(drawScene_Function); $('div#divOne').html("<canvas id='graphicsServerCanvas' width='500' height='500'></canvas>"); ]]></script>
The second script is a client of the HTML5 Canvas server. It's written in the BeanShell variant of Java, which allows it to be dynamically added to a running app. Copy the script from this wiki page, and paste it into the console in the Bestiary app. Then press the submit button.
<AlternativeGui implName="org.primordion.xholon.base.XholonNull"> <HTML5Canvas implName="org.primordion.script.Behavior_beanshell"><![CDATA[ import org.primordion.xholon.app.Application; import org.primordion.xholon.base.AbstractGrid; import org.primordion.xholon.base.IGrid; import org.primordion.xholon.base.IXholon; import org.primordion.xholon.base.IXholonClass; import org.primordion.xholon.service.IScriptService; import org.primordion.xholon.service.IXholonService; behavior() { /** The current context node. */ //private IXholon context = null; /** The xholon that owns the Row and GridCell xholons. */ private IXholon gridOwner = null; /** The Xholon application. */ private Application app = null; /** The xholon at upper left corner of the grid. */ private AbstractGrid upperLeft = null; /** Default size of a grid cell, in pixels. */ private int cellSize = 5; private int nRows = 0; private int nCols = 0; /** A service that knows how to evaluate BrowserJS and other scripts. */ private IScriptService scriptService = null; public void postConfigure() { app = applicationKey; scriptService = (IScriptService)app.getService(IXholonService.XHSRV_SCRIPT); nRows = 100; //Stage.getHeight() / cellSize; nCols = 100; //Stage.getWidth() / cellSize; gridOwner = app.getRoot().getFirstChild().getNextSibling(); setUpperLeft(); writeGuiToCanvas(); } public void act() { writeGuiToCanvas(); } protected void writeGuiToCanvas() { String data = drawGrid(); String scriptContent = createBrowserScript(data); scriptService.evalScript(contextNodeKey, "BrowserJS", scriptContent); } /** * Draw the grid to a String. * @return */ protected String drawGrid() { StringBuffer sb = new StringBuffer(); AbstractGrid currentCell = upperLeft; AbstractGrid startOfRow = upperLeft; for (int i = 0; i < nRows; i++) { //System.out.println("row:" + i); for (int j = 0; j < nCols; j++) { if (currentCell.hasChildNodes()) { sb.append(currentCell.getLastChild().getXhcId()).append(",").append(j).append(",").append(i).append("|"); } currentCell = (AbstractGrid)currentCell.port[1]; } startOfRow = (AbstractGrid)startOfRow.port[2]; currentCell = startOfRow; } return sb.toString(); } /** * Create a BrowserJS script. * @param data * @return */ protected String createBrowserScript(String data) { StringBuffer sb = new StringBuffer() .append("var myData = '").append(data).append("';") .append("var myCanvas = document.getElementById('graphicsServerCanvas');") .append("var ctx = myCanvas.getContext('2d');") .append("drawScene(ctx, myData);"); return sb.toString(); } /** * Set the xholon at the upper left corner of the grid. */ protected void setUpperLeft() { AbstractGrid row = (AbstractGrid)gridOwner.getFirstChild(); AbstractGrid col = null; while (row != null) { if (row.getXhcName().equals("Row") || row.getXhType() == IXholonClass.XhtypeGridEntity || row.getRoleName().equals("row")) { // first child of type "Row" col = (AbstractGrid)row.getFirstChild(); while (col != null) { if (col.getXhcName().equals("GridCell") || col.getXhType() == IXholonClass.XhtypeGridEntityActivePassive || col.getRoleName().equals("gridcell")) { // first child of type "GridCell" upperLeft = col; // found it return; } col = (AbstractGrid)col.getNextSibling(); } return; } row = (AbstractGrid)row.getNextSibling(); } } return this; } behaviorObject = behavior(); ]]></HTML5Canvas> </AlternativeGui>
With both GUIs running at the same time, the app is quite slow. It's a bit faster if you pause the PuplCore graphics. Click the mouse inside the PulpCore GUI (this is the original GUI on the page). Then press the P key on your keyboard, to toggle the PulpCore graphics off and on.
Internet Explorer
If you are using Internet Explorer (tested with IE 7 and 8), then the first script above cannot have any end-of-line characters in it. Here's a packed version of the first script.
<script implName="lang:BrowserJS:inline:"><![CDATA[var drawScene_Function="<script type='text/javascript'>function drawScene(ctx, theData) { ctx.fillStyle = 'green'; ctx.fillRect(0, 0, 499, 499); var rowItems = theData.split('|'); for (i in rowItems) { var colItems = rowItems[i].split(','); if (colItems.length != 3) {continue;} var id = colItems[0]; var x = colItems[1] * 5; var y = colItems[2] * 5; switch (id) { case '11': ctx.fillStyle = 'tan'; break; case '10': ctx.fillStyle = 'lightgrey'; break; case '3': ctx.fillStyle = 'white'; break; case '4': ctx.fillStyle = 'pink'; break; case '5': ctx.fillStyle = 'yellow'; break; default: ctx.fillStyle = 'magenta'; break; } ctx.fillRect(x, y, 5, 5); }};</script>";$('div#divHeadOne').html(drawScene_Function);$('div#divOne').html("<canvas id='graphicsServerCanvas' width='500' height='500'></canvas>");if(jQuery.browser.msie){var myEl=document.getElementById('graphicsServerCanvas');G_vmlCanvasManager.initElement(myEl)}]]></script>
New version with compiled Java client
server
<script implName="lang:BrowserJS:inline:"><![CDATA[ var drawScene_Function = "\ <script type='text/javascript'>\ /*\ * drawScene(context, dataFromClient)\ * id: 10=Cat 11=Human ?=Dog ?=Zombie ?=Termite\ * 15=Door 16=WallSection 17=HouseInteriorSection 18=Porch 19=Entrance\ * example of data: id,x,y\ * 1,13,20|\ * 1,16,31|\ * 2,17,15|\ * 3,17,16|\ * 1,17,21\ */\ function drawScene(ctx, theData) {\ ctx.fillStyle = 'green';\ ctx.fillRect(0, 0, 499, 499);\ var rowItems = theData.split('|');\ for (i in rowItems) {\ var colItems = rowItems[i].split(',');\ if (colItems.length != 3) {continue;}\ var id = colItems[0];\ var x = colItems[1] * 5;\ var y = colItems[2] * 5;\ /* customized for Bestiary */\ switch (id) {\ case 'Cat': ctx.fillStyle = 'lightgrey'; break;\ case 'Hum': ctx.fillStyle = 'tan'; break;\ case 'Doo': ctx.fillStyle = 'lightgreen'; break;\ case 'Wal': ctx.fillStyle = 'orange'; break;\ case 'Hou': ctx.fillStyle = 'black'; break;\ case 'Por': ctx.fillStyle = 'lightgreen'; break;\ case 'Ent': ctx.fillStyle = 'lightgreen'; break;\ case 'Dog': ctx.fillStyle = 'white'; break;\ case 'Zom': ctx.fillStyle = 'pink'; break;\ case 'Ter': ctx.fillStyle = 'yellow'; break;\ default: ctx.fillStyle = 'magenta'; break;\ }\ ctx.fillRect(x, y, 5, 5);\ }\ };\ </script>"; $('div#divHeadOne').html(drawScene_Function); $('div#divOne').html("<canvas id='graphicsServerCanvas' width='500' height='500'></canvas>"); if(jQuery.browser.msie) { var myEl = document.getElementById('graphicsServerCanvas'); G_vmlCanvasManager.initElement(myEl); } ]]></script>
use of the compiled client
<AlternativeGui implName="org.primordion.xholon.base.XholonNull"> <GridGuiDataProvider implName="org.primordion.xholon.io.GridGuiDataProvider" idType="3" idTypeAbbrevLen="3"> </GridGuiDataProvider> </AlternativeGui>
client script for testing the server
<script implName="lang:BrowserJS:inline:"><![CDATA[ var myData = 'Cat,13,20|Cat,16,31|Dog,17,15|Wal,17,16|Cat,17,21|Zom,33,33|Ter,40,40'; var myCanvas = document.getElementById('graphicsServerCanvas'); var ctx = myCanvas.getContext('2d'); drawScene(ctx, myData); ]]></script>