Metal Detector / js /
app.model.js
/* * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*global window, tizen, console*/ /** * Application model module. * It is responsible for initializing and managing magnetic sensor. * It also checks if magnetic sensor is supported. * * @module app.model * @requires {@link app.common} * @namespace app.model * @memberof app */ // make sure that "app" namespace is created window.app = window.app || {}; (function defineAppModel(app) { 'use strict'; /** * Sensor type constant string. * * @memberof app.model * @private * @const {string} */ var SENSOR_TYPE = 'MAGNETIC', /** * Magnetometer capability key. * * @memberof app.model * @private * @const {string} */ MAGNETOMETER_CAPABILITY = 'http://tizen.org/feature/sensor.magnetometer', /** * Maximal signal strength. * * @memberof app.model * @private * @const {number} */ MAX_SIGNAL_STRENGTH = 5000, /** * Error types constants. * * @memberof app.model * @public * @const {object<string, string>} * @namespace app.model.ERROR */ ERROR = Object.freeze({ /** * Error raised when magnetic sensor is not supported by * the device. * * @memberof app.model.ERROR * @const {string} */ NOT_SUPPORTED: 'not_supported', /** * Error raised when sensor start procedure fails. * * @memberof app.model.ERROR * @const {string} */ START_FAILURE: 'start_failure', /** * Raised when unknown error occurs. * * @memberof app.model.ERROR * @const {string} */ UNKNOWN: 'unknown' }), /** * Magnetic sensor object. * * @memberof app.model * @private * @type {Sensor} */ sensor = null, /** * Flag sensor started. * * @memberof app.model * @private * @type {boolean} */ isSensorStarted = false, /** * Sensor service. * * @memberof app.model * @private * @type {SensorService} */ sensorService = null, /** * Dispatches an event. * * @memberof app.model * @private * @type {function} */ dispatch = app.common.dispatchEvent; // create namespace for the module app.model = app.model || {}; /** * Converts the number value expressed in radians to degrees. * * @memberof app.model * @private * @param {number} value * @returns {number} */ function toDegrees(value) { return value * 180 / Math.PI; } /** * Returns rotation value in degrees for view elements based on * electromagnetic strength of x and y axis vectors. * * Technically: calculates resultant vector deflection degree created by * adding x and y vectors. * * @memberof app.model * @private * @param {number} x * @param {number} y * @returns {number} */ function calculateRotation(x, y) { return -toDegrees(Math.atan2(x, -y)); } /** * Returns resultant vector signal strength created from signal strength * vectors for each axis. * * @memberof app.model * @private * @param {number} x * @param {number} y * @param {number} z * @returns {number} */ function calculateSignalStrength(x, y, z) { return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)); } /** * Returns signal strength relative to maximal signal strength in * interval [0, maxNumber]. Uses logarithmic scale. * * @memberof app.model * @public * @param {number} signalStrength * @param {number} maxNumber * @returns {number} */ function calculateRelativeSignalStrength(signalStrength, maxNumber) { return Math.ceil(signalStrength > MAX_SIGNAL_STRENGTH ? maxNumber : Math.log(signalStrength) / Math.log(MAX_SIGNAL_STRENGTH) * maxNumber); } /** * Get sensor data success callback. * * @memberof app.model * @private * @fires "model.magnetic.update" * @param {SensorMagneticData} sensorData */ function onGetSuccess(sensorData) { var x = sensorData.x, y = sensorData.y, z = sensorData.z, data = { value: calculateSignalStrength(x, y, z), rotation: calculateRotation(x, y), rotationVisible: (x <= -1 || x >= 1) || (y <= -1 || y >= 1) ? true : false }; dispatch('model.magnetic.update', data); } /** * Start sensor success callback. * Sets isSensorStarted flag. * * @memberof app.model * @private * @fires "model.magnetic.ready" */ function onSensorStartSuccess() { isSensorStarted = true; dispatch('model.magnetic.ready'); try { sensor.setChangeListener(onGetSuccess); } catch (e) { console.error('Execption occured during setting thee listener', e); } } /** * Start sensor error callback. * * @memberof app.model * @private * @fires "model.magnetic.error" */ function onSensorStartError() { isSensorStarted = false; dispatch('model.magnetic.error', ERROR.START_FAILURE); } /** * Starts sensor. * Sets change listener for data. * If isSensorStarted is true returns null. * * @memberof app.model * @public */ function startSensor() { if (isSensorStarted) { return; } try { sensor.start(onSensorStartSuccess, onSensorStartError); } catch (e) { console.error('Exception occured during starting the sensor', e); onSensorStartError(); } } /** * Stops refresh sensor data. * Unsets change listener for data. * Sets isSensorStarted to false. * If isSensorStarted is false returns null. * * @memberof app.model * @public */ function stopSensor() { isSensorStarted = false; try { sensor.unsetChangeListener(); sensor.stop(); } catch (e) { console.error('Exception occurred during stopping the sensor', e); } } /** * Exits application. Stops sensor. * * @memberof app.model * @public */ function exitApplication() { if (sensor) { stopSensor(); } try { tizen.application.getCurrentApplication().exit(); } catch (e) { console.error('Error:', e.message); } } /** * Initializes module. * * @memberof app.model * @public */ function init() { var errorType = ''; // check sensor capability try { if (!tizen.systeminfo.getCapability(MAGNETOMETER_CAPABILITY)) { dispatch('model.magnetic.error', ERROR.NOT_SUPPORTED); } } catch (e) { dispatch('model.magnetic.error', ERROR.UNKNOWN); } // check if sensor is available sensorService = tizen.sensorservice || null; try { sensor = sensorService.getDefaultSensor(SENSOR_TYPE); } catch (error) { if (error.type === 'NotSupportedError') { errorType = ERROR.NOT_SUPPORTED; } else { errorType = ERROR.UNKNOWN; } dispatch('model.magnetic.error', errorType); return; } startSensor(); } app.model.ERROR = ERROR; app.model.startSensor = startSensor; app.model.stopSensor = stopSensor; app.model.calculateRelativeSignalStrength = calculateRelativeSignalStrength; app.model.exitApplication = exitApplication; app.model.init = init; })(window.app);