eclipsesource / tabris-js

Create native mobile apps in JavaScript or TypeScript.
https://tabrisjs.com
BSD 3-Clause "New" or "Revised" License
1.4k stars 170 forks source link

setTimeout/setInterval timers not working #1373

Closed dalisoft closed 7 years ago

dalisoft commented 7 years ago

Problem description

I want use the one of requestAnimationFrame (not yet anyway), setTimeout (works once and fail) or setInterval no works.

Expected behavior

I want to use own tweening engine for better flexibility as have much of easings, control over tween.

Environment

Code snippet

const textView = <TextView left={20} top={20} right={20} text="Touch anywhere..."/>.appendTo(Page1);
/* ANIMATION MODULE */
var time = 0, fps = 20, ms = 1000 / fps;
function update () {
    setTimeout(update, 50);
    textView.text = time;
    time += ms;
}
update();

// OR
/*let time = 0;
setInterval(() => {
    time += 50;
    textView.text = time;
}, 50);*/
mpost commented 7 years ago

We have a timer example which is also bundled in the store app. Could you have a look at the example?

General note when using setTimeout or setInterval you should use 0 delay since that will call you as often as possible in regards to the display refresh rate.

cpetrov commented 7 years ago

@dalisoft Please make sure you use a 2.0.0-rc2-based app. You can build your app on https://tabrisjs.com (select nightly in the Tabris.js Client Version dropdown in the job configuration. You may want to change this setting to 2.0.0-rc2 when it is released.)

We still haven't released developer clients based on 2.0.0-rc2 to the app stores. The developer app currently available on the app stores is based on Tabris.js 2.0.0 RC1 and is not compatible with tabris@2.0.0-rc2(-dev...) module versions.

dalisoft commented 7 years ago

@cpetrov @mpost I am using Tabris Dev App from Play Store. I am see demo from RC1 that timer works, but for my won't work. Just setInterval or setTimeout not working, i can't know why?

@mpost I see Timer demo, i am used the demo script, not works

dalisoft commented 7 years ago

@cpetrov @mpost. I post full my js. Even created class:

ROLLUP

import buble from 'rollup-plugin-buble';
import uglify from 'rollup-plugin-uglify';
import {
    minify
}
from 'uglify-es';

let pkg = require('./package.json');
let external = Object.keys(pkg.dependencies);

const {
    BUILD
} = process.env;

const plugins = [buble({
        jsx: 'JSX.createElement',
        transforms: {
            forOf: false
        }
    })];

if (BUILD === 'prod') {
    plugins.push(uglify({}, minify));
}

export default {
    entry: 'src/app.js',
    format: 'iife',
    dest: 'dist/App.js', // equivalent to --output
    globals: {
        'tarbis': 'Tarbis',
        'es6-tween': 'TWEEN'
    },
    moduleName: 'App',
    external,
    //exports: 'default',
    plugins: plugins
}

src/app.js

import tabris from 'tabris';

const TWEEN = require('es6-tween');

const { Animation, Page, WebView, TextView, Picker, Text, ScrollView, TabFolder, Tab, Composite, Image, ImageView, NavigationView, CollectionView, Action, Drawer, PageSelector, Button, ui } = tabris;

const { Tween, Easing } = TWEEN;

class Timer {
    constructor () {
        this.seconds = 1000;
        this.callback = null;
        this.timerTimeoutId = null;
        this.timerIntervalId = null;
    }
    setSeconds (second = 1) {
        this.seconds = second * 1000;
        return this;
    }
    setCallback (callback) {
        this.callback = callback;
        return this;
    }
    setInterval () {
        this.timerIntervalId = window.setInterval(this.callback.bind(this), this.seconds);
        return this;
    }
    setTimeout () {
        this.timerTimeoutId = window.setTimeout(this.callback.bind(this), this.seconds);
        return this;
    }
    clear (type) {
        if (type === 'timeout') {
            clearTimeout(this.timerTimeoutId);
        } else if (type === 'interval') {
            clearInterval(this.timerIntervalId);
        }
        return this;
    }
}

const navigationView = <NavigationView left={0} top={0} right={0} bottom={0}/>.appendTo(ui.contentView);
const Page1 = <Page title="Page"/>.appendTo(navigationView);
const textView = <TextView left={20} top={20} right={20} text="Touch anywhere..."/>.appendTo(Page1);

let timerId = new Timer().setSeconds(1).setCallback(() => {
    textView.text = new Date().getTime().toString();
});
const Btn = <Button text="Go back" left={16} top={[textView, 10]} right={16}/>.on('select', () => {
    setInterval(function(){
        textView.text = new Date.getTime().toString(); // NO LUCK HERE
    }, 20);
    textView.text = 'Button was clicked and the ' + typeof setInterval; // WORKS AND SAID IT'S FUNCTION
    try {
        timerId.setTimeout();
        textView.text !== 'Button was clicked';
    } catch (e) {
        textView.text = new Date.getTime().toString() + ' ms is and the button is fail from timeout and err: ' + JSON.stringify(e);
    }
}).appendTo(Page1);

/* ANIMATION MODULE */

ui.contentView.on({
    longpress: ({touches}) => {
        textView.text = JSON.stringify(touches);

    }
});
cpetrov commented 7 years ago

@dalisoft Please change your tabris dependency to tabris@2.0.0-rc1 if you are using the developer client.

dalisoft commented 7 years ago

package.json

{
  "name": "my-sample-app",
  "version": "0.1.0",
  "main": "dist/App.js",
  "private": false,
  "scripts": {
    "test": "eslint .",
    "start": "tabris serve",
    "build": "rollup -c --environment BUILD:prod",
    "source": "rollup -c --sourcemap",
    "prepublish": "npm run source && npm run build",
    "dev": "rollup -c -w --sourcemap"
  },
  "dependencies": {
    "tabris": "^2.0.0-rc1"
  },
  "devDependencies": {
    "eslint": "^3.19.0",
    "rollup": "^0.41.6",
    "rollup-plugin-buble": "^0.15.0",
    "rollup-plugin-uglify": "^2.0.1",
    "rollup-watch": "^3.2.2",
    "uglify-es": "^3.0.11"
  }
}
dalisoft commented 7 years ago

@cpetrov i am use package.json as is, after created via tabris init

maoamid commented 7 years ago

@dalisoft there is a typo in rollup file, see bellow: globals: { 'tarbis': 'Tarbis', 'es6-tween': 'TWEEN' },

dalisoft commented 7 years ago

But buttons, etc... works except the Timer. Even JSX workers. @maoamid i fixed typo, still no works the timer

dalisoft commented 7 years ago

@maoamid @cpetrov The original timer demo script is won't work, i not sure why? maybe the script file i changed

dalisoft commented 7 years ago

You're can look to app at here

cpetrov commented 7 years ago

@dalisoft Since Tabris.js 2 RC2 is now released, ^2.0.0-rc1 will resolve to 2.0.0-rc2.

We have just released RC2, so you can update your developer client (Android/iOS). I could successfully run your app with the latest developer client.

There are two problems in your code though where the Date constructor is not invoked properly:

app.js L46: textView.text = new Date.getTime().toString(); // new Date()... L53: textView.text = new Date.getTime().toString() + ' ms is and the ...' + // new Date()...

dalisoft commented 7 years ago

@cpetrov Thanks. I don't sure why VSCode not get this error

dalisoft commented 7 years ago

Thanks for all who helped and fixed the issue i have. Now it runs fine. Finally i've get what i need. Now start making fanapp. Thanks a lot