mil-sym.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. // Copyright 2012 United States Government, as represented by the Secretary of Defense, Under
  2. // Secretary of Defense (Personnel & Readiness).
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  5. // in compliance with the License. You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software distributed under the License
  10. // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  11. // or implied. See the License for the specific language governing permissions and limitations under
  12. // the License.
  13. /// vwf/model/test.js is a dummy driver used for tests.
  14. ///
  15. /// @module vwf/model/test
  16. /// @requires vwf/model
  17. define( [ "module",
  18. "vwf/model",
  19. "vwf/utility",
  20. "vwf/utility/color",
  21. "mil-sym/cws",
  22. "jquery" ],
  23. function( module, model, utility, Color, cws, $ ) {
  24. var modelDriver;
  25. return model.load( module, {
  26. // == Module Definition ====================================================================
  27. // -- initialize ---------------------------------------------------------------------------
  28. initialize: function( options ) {
  29. modelDriver = this;
  30. this.arguments = Array.prototype.slice.call( arguments );
  31. if ( options === undefined ) { options = {}; }
  32. this.state = {
  33. "nodes": {},
  34. "prototypes": {},
  35. "createNode": function( nodeType, nodeID, childID, childExtendsID, childImplementsIDs,
  36. childSource, childType, childIndex, childName, callback ) {
  37. return {
  38. "nodeType": nodeType,
  39. "parentID": nodeID,
  40. "ID": childID,
  41. "extendsID": childExtendsID,
  42. "implementsIDs": childImplementsIDs,
  43. "source": childSource,
  44. "type": childType,
  45. "name": childName
  46. };
  47. }
  48. };
  49. // turns on logger debugger console messages
  50. this.debug = {
  51. "creation": false,
  52. "initializing": false,
  53. "parenting": false,
  54. "deleting": false,
  55. "properties": false,
  56. "setting": false,
  57. "getting": false,
  58. "prototypes": false
  59. };
  60. },
  61. creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
  62. childSource, childType, childIndex, childName, callback ) {
  63. // If the parent nodeID is 0, this node is attached directly to the root and is therefore either
  64. // the scene or a prototype. In either of those cases, save the uri of the new node
  65. var childURI = ( nodeID === 0 ? childIndex : undefined );
  66. var appID = this.kernel.application();
  67. if ( this.debug.creation ) {
  68. this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childName );
  69. }
  70. // If the node being created is a prototype, construct it and add it to the array of prototypes,
  71. // and then return
  72. var prototypeID = utility.ifPrototypeGetId( appID, this.state.prototypes, nodeID, childID );
  73. if ( prototypeID !== undefined ) {
  74. if ( this.debug.prototypes ) {
  75. this.logger.infox( "prototype: ", prototypeID );
  76. }
  77. this.state.prototypes[ prototypeID ] = {
  78. parentID: nodeID,
  79. ID: childID,
  80. extendsID: childExtendsID,
  81. implementsID: childImplementsIDs,
  82. source: childSource,
  83. type: childType,
  84. uri: childURI,
  85. name: childName,
  86. };
  87. return;
  88. }
  89. var protos = getPrototypes( childExtendsID );
  90. var node = this.state.nodes[ childID ];
  91. if ( node === undefined ) {
  92. if ( isUnitNode( protos ) ) {
  93. this.state.nodes[ childID ] = node = this.state.createNode( "unit", nodeID, childID, childExtendsID, childImplementsIDs,
  94. childSource, childType, childIndex, childName, callback );
  95. // additional members for the unit components
  96. node.symbolID = undefined;
  97. node.modifiers = {};
  98. node.image = undefined;
  99. node.description = undefined;
  100. node.tagName = undefined;
  101. node.fullName = undefined;
  102. node.echelon = undefined;
  103. node.affiliation = undefined;
  104. } else if ( isModifierNode( protos ) ) {
  105. this.state.nodes[ childID ] = node = this.state.createNode( "modifier", nodeID, childID, childExtendsID, childImplementsIDs,
  106. childSource, childType, childIndex, childName, callback );
  107. }
  108. }
  109. },
  110. initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
  111. childSource, childType, childIndex, childName ) {
  112. if ( this.debug.initializing ) {
  113. this.logger.infox( "initializingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childName );
  114. }
  115. },
  116. deletingNode: function( nodeID ) {
  117. if ( this.debug.deleting ) {
  118. this.logger.infox( "deletingNode", nodeID );
  119. }
  120. if ( this.state.nodes[ nodeID ] !== undefined ) {
  121. delete this.state.nodes[ nodeID ];
  122. }
  123. },
  124. // addingChild: function( nodeID, childID, childName ) {
  125. // if ( this.debug.parenting ) {
  126. // this.logger.infox( "addingChild", nodeID, childID, childName );
  127. // }
  128. // },
  129. // movingChild: function( nodeID, childID, childName ) {
  130. // if ( this.debug.parenting ) {
  131. // this.logger.infox( "movingChild", nodeID, childID, childName );
  132. // }
  133. // },
  134. // removingChild: function( nodeID, childID, childName ) {
  135. // if ( this.debug.parenting ) {
  136. // this.logger.infox( "removingChild", nodeID, childID, childName );
  137. // }
  138. // },
  139. // -- creatingProperty ---------------------------------------------------------------------
  140. creatingProperty: function( nodeID, propertyName, propertyValue ) {
  141. if ( this.debug.properties ) {
  142. this.logger.infox( "C === creatingProperty ", nodeID, propertyName, propertyValue );
  143. }
  144. return this.settingProperty( nodeID, propertyName, propertyValue );
  145. },
  146. // -- initializingProperty -----------------------------------------------------------------
  147. initializingProperty: function( nodeID, propertyName, propertyValue ) {
  148. if ( this.debug.properties ) {
  149. this.logger.infox( " I === initializingProperty ", nodeID, propertyName, propertyValue );
  150. }
  151. return this.settingProperty( nodeID, propertyName, propertyValue );
  152. },
  153. // -- settingProperty ----------------------------------------------------------------------
  154. settingProperty: function( nodeID, propertyName, propertyValue ) {
  155. if ( this.debug.properties || this.debug.setting ) {
  156. this.logger.infox( " S === settingProperty ", nodeID, propertyName, propertyValue );
  157. }
  158. var node = this.state.nodes[ nodeID ];
  159. var value = undefined;
  160. var renderImage = false;
  161. if ( node !== undefined && ( utility.validObject( propertyValue ) ) ) {
  162. if ( node.nodeType === "unit" ) {
  163. switch ( propertyName ) {
  164. case "symbolID":
  165. value = node.symbolID = propertyValue;
  166. if ( node.echelon !== undefined ) {
  167. node.symbolID = cws.addEchelonToSymbolId( node.symbolID, node.echelon );
  168. }
  169. if ( node.affiliation !== undefined ) {
  170. node.symbolID = cws.addAffiliationToSymbolId( node.symbolID, node.affiliation );
  171. }
  172. renderImage = true;
  173. break;
  174. case "image":
  175. value = node.image = propertyValue;
  176. break;
  177. case "description":
  178. value = node.description = propertyValue;
  179. break;
  180. case "tagName":
  181. value = node.tagName = propertyValue;
  182. break;
  183. case "fullName":
  184. value = node.fullName = propertyValue;
  185. break;
  186. case "echelon":
  187. if ( node.echelon !== propertyValue ) {
  188. switch( propertyValue ) {
  189. case "team":
  190. case "crew":
  191. case "squad":
  192. case "section":
  193. case "platoon":
  194. case "detachment":
  195. case "company":
  196. case "battery":
  197. case "troop":
  198. case "battalion":
  199. case "squadron":
  200. case "regiment":
  201. case "group":
  202. case "brigade":
  203. case "division":
  204. case "corps":
  205. case "mef":
  206. case "army":
  207. case "army group":
  208. case "front":
  209. case "region":
  210. case "null":
  211. case "none":
  212. if ( node.symbolID !== undefined ) {
  213. node.symbolID = cws.addEchelonToSymbolId( node.symbolID, propertyValue );
  214. }
  215. node.echelon = propertyValue;
  216. renderImage = true;
  217. break;
  218. default:
  219. this.logger.warnx( "incorrect echelon property value: " + propertyValue );
  220. break;
  221. }
  222. }
  223. break;
  224. case "affiliation":
  225. if ( node.affiliation !== propertyValue ) {
  226. switch( propertyValue ) {
  227. case "unknown":
  228. case "neutral":
  229. case "hostile":
  230. case "friendly":
  231. if ( node.symbolID !== undefined ) {
  232. node.symbolID = cws.addAffiliationToSymbolId( node.symbolID, propertyValue );
  233. }
  234. node.affiliation = propertyValue;
  235. renderImage = true;
  236. break;
  237. default:
  238. this.logger.warnx( "incorrect affiliation property value: " + propertyValue );
  239. break;
  240. }
  241. }
  242. break;
  243. }
  244. } else if ( node.nodeType === "modifier" ) {
  245. var unit = this.state.nodes[ node.parentID ];
  246. var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes;
  247. var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits;
  248. if ( unit === undefined ) {
  249. return undefined;
  250. }
  251. // Render image if modifier is valid
  252. renderImage = setModifier( unit, propertyName, propertyValue );
  253. }
  254. }
  255. if ( node !== undefined ) {
  256. // if node is defined then it is either a unit or a modifier
  257. // if nodeType is a modifier, then the parent is the unit
  258. var unitNode = node.nodeType === "modifier" ? this.state.nodes[ node.parentID ] : node;
  259. if ( unitNode && renderImage ) {
  260. render( unitNode );
  261. }
  262. }
  263. return value;
  264. },
  265. // -- gettingProperty ----------------------------------------------------------------------
  266. gettingProperty: function( nodeID, propertyName ) {
  267. if ( this.debug.properties || this.debug.getting ) {
  268. this.logger.infox( " G === gettingProperty ", nodeID, propertyName );
  269. }
  270. var node = this.state.nodes[ nodeID ];
  271. var value = undefined;
  272. //this driver has no representation of this node, so there is nothing to do.
  273. if( node === undefined ) return value;
  274. if ( node.nodeType === "unit" ) {
  275. switch ( propertyName ) {
  276. case "symbolID":
  277. value = node.symbolID;
  278. break;
  279. case "image":
  280. value = node.image;
  281. break;
  282. case "description":
  283. value = node.description;
  284. break;
  285. case "fullName":
  286. value = node.fullName;
  287. break;
  288. case "tagName":
  289. value = node.tagName;
  290. break;
  291. }
  292. } else if ( node.nodeType === "modifier" ) {
  293. var unit = this.state.nodes[ node.parentID ];
  294. var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes;
  295. var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits;
  296. if ( unit === undefined ) {
  297. return undefined;
  298. }
  299. value = getModifier( unit, propertyName );
  300. }
  301. return value;
  302. },
  303. // -- callingMethod --------------------------------------------------------------------------
  304. callingMethod: function( nodeID, methodName /* [, parameter1, parameter2, ... ] */ ) { // TODO: parameters
  305. var node = this.state.nodes[ nodeID ];
  306. var value = undefined;
  307. switch( methodName ) {
  308. case "render":
  309. value = render( node );
  310. break;
  311. }
  312. return value;
  313. },
  314. // TODO: creatingEvent, deltetingEvent, firingEvent
  315. // -- executing ------------------------------------------------------------------------------
  316. // executing: function( nodeID, scriptText, scriptType ) {
  317. // return undefined;
  318. // },
  319. // == ticking =============================================================================
  320. // ticking: function( vwfTime ) {
  321. // }
  322. } );
  323. function getPrototypes( extendsID ) {
  324. var prototypes = [];
  325. var id = extendsID;
  326. while ( id !== undefined ) {
  327. prototypes.push( id );
  328. id = modelDriver.kernel.prototype( id );
  329. }
  330. return prototypes;
  331. }
  332. function isUnitNode( prototypes ) {
  333. var found = false;
  334. if ( prototypes ) {
  335. for ( var i = 0; i < prototypes.length && !found; i++ ) {
  336. found = ( prototypes[i] == "http://vwf.example.com/mil-sym/unit.vwf" );
  337. }
  338. }
  339. return found;
  340. }
  341. function isModifierNode( prototypes ) {
  342. var found = false;
  343. if ( prototypes ) {
  344. for ( var i = 0; i < prototypes.length && !found; i++ ) {
  345. found = ( prototypes[i] == "http://vwf.example.com/mil-sym/modifier.vwf" );
  346. }
  347. }
  348. return found;
  349. }
  350. function render( node ) {
  351. if ( node === undefined ) {
  352. return;
  353. }
  354. var value = undefined;
  355. if ( node !== undefined && node.nodeType === "unit" && node.symbolID !== undefined ) {
  356. var iconRender = armyc2.c2sd.renderer.MilStdIconRenderer;
  357. var img = iconRender.Render( node.symbolID, node.modifiers );
  358. var centerPt = img.getCenterPoint();
  359. var imgSize = img.getImageBounds();
  360. var symbolBounds = img.getSymbolBounds();
  361. value = node.image = img.toDataUrl();
  362. // we should really use the event, but we're having troubles
  363. // getting the events to replicate, this should be switched
  364. // back to the event when the replication is fixed. handleRender
  365. // can then be completely removed
  366. //modelDriver.kernel.fireEvent( node.ID, "imageRendered", [ node.image, imgSize, centerPt, symbolBounds ] );
  367. modelDriver.kernel.callMethod( node.ID, "handleRender", [ node.image, imgSize, centerPt, symbolBounds ] );
  368. }
  369. return value;
  370. }
  371. function setModifier( unit, modifierAlias, modifierValue ) {
  372. var modObj = cws.modifierByAlias( modifierAlias );
  373. var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes;
  374. var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits;
  375. var modifierSet = false;
  376. if ( modObj !== undefined ) {
  377. var modifierActualName;
  378. switch ( modObj.type ) {
  379. case "ModifiersUnits":
  380. modifierActualName = mu[ modObj.modifier ];
  381. break;
  382. case "MilStdAttributes":
  383. modifierActualName = msa[ modObj.modifier ];
  384. break;
  385. default:
  386. modelDriver.logger.errorx( "setModifier", "Unknown type (", modObj.type, ") specified." );
  387. return modifierSet;
  388. }
  389. if ( modifierValue === "" ) {
  390. if ( unit.modifiers[ modifierActualName ] !== undefined ) {
  391. delete unit.modifiers[ modifierActualName ];
  392. modifierSet = true;
  393. }
  394. } else {
  395. switch ( modObj.valueType ) {
  396. case "Boolean":
  397. unit.modifiers[ modifierActualName ] = Boolean(modifierValue);
  398. break;
  399. case "Number":
  400. unit.modifiers[ modifierActualName ] = Number(modifierValue);
  401. break;
  402. case "Array":
  403. case "Text":
  404. default:
  405. unit.modifiers[ modifierActualName ] = modifierValue;
  406. break;
  407. }
  408. modifierSet = true;
  409. }
  410. }
  411. return modifierSet;
  412. }
  413. function getModifier( unit, modifierAlias ) {
  414. var modObj = cws.modifierByAlias( modifierAlias );
  415. var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes;
  416. var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits;
  417. var value = undefined;
  418. if ( modObj !== undefined ) {
  419. var modifierActualName;
  420. switch ( modObj.type ) {
  421. case "ModifiersUnits":
  422. modifierActualName = mu[ modObj.modifier ];
  423. break;
  424. case "MilStdAttributes":
  425. modifierActualName = msa[ modObj.modifier ];
  426. break;
  427. default:
  428. modelDriver.logger.errorx( "getModifier", "Unknown type (", modObj.type, ") specified." );
  429. return value;
  430. }
  431. value = unit.modifiers[ modifierActualName ];
  432. }
  433. return value;
  434. }
  435. } );