Table of Contents
News for November 2006November 9Programming styleThe next release of the plugin API will come with some 'wrapper' classes to make the lives of plugin developers just a little bit easier (if they choose to use them, that is.) In this post I'm going to demonstrate the changes by writing the same piece of plugin code with and without the wrapper classes. This particular example retrieves the heightfield, asks the user for a 'level' value (float), and then sets every pixel in the heightfield to that value. Firstly, the basic API code: // get the heightfield ZMAP hMap; if(!(hMap = theAPI.map_GetMap("project.HF"))) return false; // check that it is a heightfield if(theAPI.map_GetMapType(hMap)!=MAP_Heightfield) return false; // create a temp var for the level setting ZVAR hVar; if(!(hVar = theAPI.var_Create(VarID_float, "level"))) return false; // open edit user interface for level setting if(!theAPI.var_EditUI(hVar, "Enter level (m)")) { theAPI.var_Delete(hVar); return false; } // get the value float level; theAPI.var_GetValueEx(hVar, VarID_float, &level); // apply level setting to all pixels in map bool ErrorFlag = false; for(int j=0; j<theAPI.map_GetHeight(hMap) && !ErrorFlag; j++) { for(int i=0; i<theAPI.map_GetWidth(hMap) && !ErrorFlag; i++) { if(!theAPI.map_SetPixel(hMap, i, j, &level)) { ErrorFlag = true; } } } // cleanup theAPI.var_Delete(hVar); if(ErrorFlag) return false; return true; I think you'll agree that was a little torturous, particularly with all those brackets, ZVAR handles and function calls to 'theAPI'. Note I also had to be careful to delete the temporary hVar I had created, as forgetting to do so would have leaked a few bytes of memory. Here is the code again, using the CzMap and CzVar wrappers: // get the heightfield CzMap zmap; if(!zmap.GetByName("project.HF")) return false; // check that it is a heightfield if(zmap.GetMapType()!=MAP_Heightfield) return false; // create a temp var for the level setting CzVar TempVar; if(!TempVar.Create(VarID_float, "level")) return false; // open edit user interface for level setting if(!theAPI.var_EditUI(TempVar.GetZVAR(), "Enter level (m)")) return false; // get the value float level; TempVar.GetValue(VarID_float, &level); // apply level setting to all pixels in map bool ErrorFlag = false; for(int j=0; j<zmap.ny() && !ErrorFlag; j++) { for(int i=0; i<zmap.nx() && !ErrorFlag; i++) { if(!zmap.SetPixel(i, j, &level)) { ErrorFlag = true; } } } if(ErrorFlag) return false; There are probably two things to notice here. One is that we're now using object oriented programming, so we've largely dispensed with the ZVAR handles and theAPI calls. The second is that the variables now obey scoping rules, so I don't have to call 'theAPI.var_Delete(hVar);' to clean up any more, and I don't have to worry about leaking memory. Finally, for one last comparison, here is the equivalent 'native' code from L3DT: // get the heightfield CMapWrap* pMap; if(!GetMap("HF", &pMap)) return false; // check that it is a heightfield if(!pMap->IsInitType(MAP_Heightfield)) return false; // create a temp var for the level setting CVar TempVar; float* pFloat; if(!TempVar.CreateAndGetData(VTID_float, "level", (void**)&pFloat)) return false; // open edit user interface for level setting if(!VarUI_EditVar(&TempVar, "Enter level (m)")) return false; // apply level setting to all pixels in map bool ErrorFlag = false; for(int j=0; j<pMap->ny() && !ErrorFlag; j++) { for(int i=0; i<pMap->nx() && !ErrorFlag; i++) { if(!pMap->SetPixel(i, j, pFloat)) { ErrorFlag = true; } } } if(ErrorFlag) return false; return true; This is all object oriented too, and slightly more terse, but you'll note that it uses lots of pointers, and also some pointers to pointers. The plugin API, with wrapper classes, hides this complexity without compromising utility. I hope you'll like using it as much as I do. Cheers, Aaron. UpdateThe wrapper-ification is complete (for now.) I've added wrappers for generic variables, strings, variable lists, maps, file formats, extension functions, buffers, and progress boxes. There should be an updated API released next week sometime. Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Share Alike 3.0 Unported
|