diff --git a/src/js/phet-converter.js b/src/js/phet-converter.js index 1444e5a..db63265 100644 --- a/src/js/phet-converter.js +++ b/src/js/phet-converter.js @@ -16,7 +16,7 @@ fluid.defaults("phetosc.converter", { bundleParameters: true, - addressTemplate: "/%phetioID/%eventType/%event/", + addressTemplate: "/%phetioID/%eventType/%event", jsToOSCTypes: { "number": "d", @@ -41,7 +41,7 @@ phetosc.converter.visitPhETEvents = function (phetEvent, options, packets, event eventVisitor(phetEvent, options, packets); fluid.each(phetEvent.children, function (childEvent) { - phetosc.converter.visitPhETEvents(childEvent, packets, eventVisitor); + phetosc.converter.visitPhETEvents(childEvent, options, packets, eventVisitor); }); }; @@ -80,6 +80,13 @@ phetosc.converter.messageAddressPrefix = function (phetEvent, options) { }; phetosc.converter.objectToMessages = function (obj, addressPrefix, options, packets) { + if (!obj || Object.keys(obj) < 1) { + // TODO: Rearrange argument order? + phetosc.converter.toMessage(undefined, addressPrefix, undefined, options, packets); + return; + } + + addressPrefix = addressPrefix + "/"; fluid.each(obj, function (val, key) { phetosc.converter.parameterToMessages(val, key, addressPrefix, options, packets); }); @@ -96,22 +103,25 @@ phetosc.converter.parameterToMessages = function (val, key, addressPrefix, optio parameterType = typeof val; if (parameterType === "object") { - return phetosc.converter.objectToMessages(val, address + "/", options, packets); + return phetosc.converter.objectToMessages(val, address, options, packets); } else { - return phetosc.converter.primitiveToMessage(val, address, parameterType, options, packets); + return phetosc.converter.toMessage(val, address, parameterType, options, packets); } }; -phetosc.converter.primitiveToMessage = function (val, address, parameterType, options, packets) { +phetosc.converter.toMessage = function (val, address, parameterType, options, packets) { var message = { - address: address, - args: [ + address: address + }; + + if (val !== undefined) { + message.args = [ { type: phetosc.converter.oscTypeForJSType(parameterType, options.jsToOSCTypes), value: val } ] - }; + } packets.push(message); }; diff --git a/tests/data/osc/osc-composite-event-drag-ended-bundled.json b/tests/data/osc/osc-composite-event-drag-ended-bundled.json new file mode 100644 index 0000000..f3d903f --- /dev/null +++ b/tests/data/osc/osc-composite-event-drag-ended-bundled.json @@ -0,0 +1,282 @@ +[ + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.view.nucleons_9.inputListener/user/dragEnded" + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.model.protons_9.userControlledProperty/model/changed/oldValue", + "args": [ + { + "type": "b", + "value": true + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.model.protons_9.userControlledProperty/model/changed/newValue", + "args": [ + { + "type": "b", + "value": false + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.protonCountProperty/model/changed/oldValue", + "args": [ + { + "type": "d", + "value": 0 + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.protonCountProperty/model/changed/newValue", + "args": [ + { + "type": "d", + "value": 1 + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.chargeProperty/model/changed/oldValue", + "args": [ + { + "type": "d", + "value": 0 + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.chargeProperty/model/changed/newValue", + "args": [ + { + "type": "d", + "value": 1 + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.view.chargeMeter.readoutText/model/textChanged/oldText", + "args": [ + { + "type": "s", + "value": "0" + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.view.chargeMeter.readoutText/model/textChanged/newText", + "args": [ + { + "type": "s", + "value": "+1" + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.massNumberProperty/model/changed/oldValue", + "args": [ + { + "type": "d", + "value": 0 + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.massNumberProperty/model/changed/newValue", + "args": [ + { + "type": "d", + "value": 1 + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.view.massNumberDisplay.numericalText/model/textChanged/oldText", + "args": [ + { + "type": "s", + "value": "0" + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.view.massNumberDisplay.numericalText/model/textChanged/newText", + "args": [ + { + "type": "s", + "value": "1" + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.particleCountProperty/model/changed/oldValue", + "args": [ + { + "type": "d", + "value": 0 + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.particleCountProperty/model/changed/newValue", + "args": [ + { + "type": "d", + "value": 1 + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.view.atomNode.elementName/model/textChanged/oldText", + "args": [ + { + "type": "s", + "value": "" + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.view.atomNode.elementName/model/textChanged/newText", + "args": [ + { + "type": "s", + "value": "‪Hydrogen‬" + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.view.atomNode.ionIndicator/model/textChanged/oldText", + "args": [ + { + "type": "s", + "value": "" + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.view.atomNode.ionIndicator/model/textChanged/newText", + "args": [ + { + "type": "s", + "value": "‪+ Ion‬" + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.view.atomNode.stabilityIndicator/model/textChanged/oldText", + "args": [ + { + "type": "s", + "value": "" + } + ] + }, + { + "address": "/buildAnAtom.atomScreen.view.atomNode.stabilityIndicator/model/textChanged/newText", + "args": [ + { + "type": "s", + "value": "‪Stable‬" + } + ] + } + ] + }, + { + "packets": [ + { + "address": "/buildAnAtom.atomScreen.model.particleAtom.protons/model/itemAdded/item", + "args": [ + { + "type": "s", + "value": "TParticle" + } + ] + } + ] + }, + { + "packets": [ + { + "address":"/buildAnAtom.atomScreen.model.protons_9.destinationProperty/model/changed/oldValue/x", + "args": [ + { + "type": "d", + "value": -9.20000000000003 + } + ] + }, + { + "address":"/buildAnAtom.atomScreen.model.protons_9.destinationProperty/model/changed/oldValue/y", + "args": [ + { + "type": "d", + "value": -41.360000000000014 + } + ] + }, + { + "address":"/buildAnAtom.atomScreen.model.protons_9.destinationProperty/model/changed/newValue/x", + "args": [ + { + "type": "d", + "value": 0 + } + ] + }, + { + "address":"/buildAnAtom.atomScreen.model.protons_9.destinationProperty/model/changed/newValue/y", + "args": [ + { + "type": "d", + "value": 0 + } + ] + } + ] + } +] diff --git a/tests/data/phet/phet-composite-event-drag-ended.json b/tests/data/phet/phet-composite-event-drag-ended.json new file mode 100644 index 0000000..b31b5b7 --- /dev/null +++ b/tests/data/phet/phet-composite-event-drag-ended.json @@ -0,0 +1,169 @@ +[ + { + "messageIndex": 229, + "eventType": "user", + "phetioID": "buildAnAtom.atomScreen.view.nucleons_9.inputListener", + "componentType": "TTandemSimpleDragHandler", + "event": "dragEnded", + "time": 1495058799750, + "children": [ + { + "messageIndex": 230, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.protons_9.userControlledProperty", + "componentType": "TProperty", + "event": "changed", + "time": 1495058799751, + "parameters": { + "oldValue": true, + "newValue": false + }, + "children": [ + { + "messageIndex": 231, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.particleAtom.protonCountProperty", + "componentType": "TDerivedProperty", + "event": "changed", + "time": 1495058799751, + "parameters": { + "oldValue": 0, + "newValue": 1 + }, + "children": [ + { + "messageIndex": 232, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.particleAtom.chargeProperty", + "componentType": "TDerivedProperty", + "event": "changed", + "time": 1495058799751, + "parameters": { + "oldValue": 0, + "newValue": 1 + }, + "children": [ + { + "messageIndex": 233, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.view.chargeMeter.readoutText", + "componentType": "TText", + "event": "textChanged", + "time": 1495058799751, + "parameters": { + "oldText": "0", + "newText": "+1" + } + } + ] + }, + { + "messageIndex": 234, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.particleAtom.massNumberProperty", + "componentType": "TDerivedProperty", + "event": "changed", + "time": 1495058799752, + "parameters": { + "oldValue": 0, + "newValue": 1 + }, + "children": [ + { + "messageIndex": 235, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.view.massNumberDisplay.numericalText", + "componentType": "TText", + "event": "textChanged", + "time": 1495058799752, + "parameters": { + "oldText": "0", + "newText": "1" + } + } + ] + }, + { + "messageIndex": 236, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.particleAtom.particleCountProperty", + "componentType": "TDerivedProperty", + "event": "changed", + "time": 1495058799752, + "parameters": { + "oldValue": 0, + "newValue": 1 + } + }, + { + "messageIndex": 237, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.view.atomNode.elementName", + "componentType": "TText", + "event": "textChanged", + "time": 1495058799753, + "parameters": { + "oldText": "", + "newText": "‪Hydrogen‬" + } + }, + { + "messageIndex": 238, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.view.atomNode.ionIndicator", + "componentType": "TText", + "event": "textChanged", + "time": 1495058799754, + "parameters": { + "oldText": "", + "newText": "‪+ Ion‬" + } + }, + { + "messageIndex": 239, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.view.atomNode.stabilityIndicator", + "componentType": "TText", + "event": "textChanged", + "time": 1495058799754, + "parameters": { + "oldText": "", + "newText": "‪Stable‬" + } + } + ] + }, + { + "messageIndex": 240, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.particleAtom.protons", + "componentType": "TObservableArray", + "event": "itemAdded", + "time": 1495058799756, + "parameters": { + "item": "TParticle" + } + }, + { + "messageIndex": 241, + "eventType": "model", + "phetioID": "buildAnAtom.atomScreen.model.protons_9.destinationProperty", + "componentType": "TProperty", + "event": "changed", + "time": 1495058799756, + "parameters": { + "oldValue": { + "x": -9.20000000000003, + "y": -41.360000000000014 + }, + "newValue": { + "x": 0, + "y": 0 + } + } + } + ] + } + ] + } +] diff --git a/tests/js/phet-converter-tests.js b/tests/js/phet-converter-tests.js index 8530ae1..adaf2d7 100644 --- a/tests/js/phet-converter-tests.js +++ b/tests/js/phet-converter-tests.js @@ -75,7 +75,7 @@ fluid.defaults("phetosc.tests.converter.primitiveValueChanged", { }); phetosc.tests.converter.runTests = function (that, phetEvent, expected) { - jqUnit.test("Primitive value changed", function () { + jqUnit.test("Conversion from PhET event to OSC messages", function () { var actual = that.converter.toOSC(phetEvent); jqUnit.assertDeepEq("PhET event was correctly converted to OSC messages", expected, actual); @@ -104,6 +104,19 @@ fluid.defaults("phetosc.tests.converter.objectParameter", { oscPath: "../data/osc/osc-object-valued-parameter-bundled.json" }); +fluid.defaults("phetosc.tests.converter.compositeEvent", { + gradeNames: [ + "phetosc.tests.withBundledConverter", + "phetosc.tests.deepEqConversionTester" + ], + + moduleName: "Composite event with children, bundled", + + phetPath: "../data/phet/phet-composite-event-drag-ended.json", + oscPath: "../data/osc/osc-composite-event-drag-ended-bundled.json" +}); + phetosc.tests.converter.primitiveValueChanged(); phetosc.tests.converter.primitiveUnbundledValueChange(); phetosc.tests.converter.objectParameter(); +phetosc.tests.converter.compositeEvent();