Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 6 files). Show all
Unified · Split
| @@ -573,7 +573,6 @@ void ScriptEngine::registerValue(const QString& valueName, QScriptValue value) { · 572 unmodified lines | ||
| 573 | 573 | QMetaObject::invokeMethod(this, "registerValue", |
| 574 | 574 | Q_ARG(const QString&, valueName), |
| 575 | 575 | Q_ARG(QScriptValue, value)); |
| 576 | − _hasInvokeMethod.wakeAll(); | |
| 577 | 576 | return; |
| 578 | 577 | } |
| 579 | 578 | |
| @@ -604,7 +603,6 @@ void ScriptEngine::registerGlobalObject(const QString& name, QObject* object) { · 24 unmodified lines | ||
| 604 | 603 | QMetaObject::invokeMethod(this, "registerGlobalObject", |
| 605 | 604 | Q_ARG(const QString&, name), |
| 606 | 605 | Q_ARG(QObject*, object)); |
| 607 | − _hasInvokeMethod.wakeAll(); | |
| 608 | 606 | return; |
| 609 | 607 | } |
| 610 | 608 | #ifdef THREAD_DEBUGGING |
| @@ -630,7 +628,6 @@ void ScriptEngine::registerFunction(const QString& name, QScriptEngine::Function · 19 unmodified lines | ||
| 630 | 628 | Q_ARG(const QString&, name), |
| 631 | 629 | Q_ARG(QScriptEngine::FunctionSignature, functionSignature), |
| 632 | 630 | Q_ARG(int, numArguments)); |
| 633 | − _hasInvokeMethod.wakeAll(); | |
| 634 | 631 | return; |
| 635 | 632 | } |
| 636 | 633 | #ifdef THREAD_DEBUGGING |
| @@ -650,7 +647,6 @@ void ScriptEngine::registerFunction(const QString& parent, const QString& name, · 13 unmodified lines | ||
| 650 | 647 | Q_ARG(const QString&, name), |
| 651 | 648 | Q_ARG(QScriptEngine::FunctionSignature, functionSignature), |
| 652 | 649 | Q_ARG(int, numArguments)); |
| 653 | − _hasInvokeMethod.wakeAll(); | |
| 654 | 650 | return; |
| 655 | 651 | } |
| 656 | 652 | #ifdef THREAD_DEBUGGING |
| @@ -676,7 +672,6 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func · 19 unmodified lines | ||
| 676 | 672 | Q_ARG(QScriptEngine::FunctionSignature, getter), |
| 677 | 673 | Q_ARG(QScriptEngine::FunctionSignature, setter), |
| 678 | 674 | Q_ARG(const QString&, parent)); |
| 679 | − _hasInvokeMethod.wakeAll(); | |
| 680 | 675 | return; |
| 681 | 676 | } |
| 682 | 677 | #ifdef THREAD_DEBUGGING |
| @@ -709,7 +704,6 @@ void ScriptEngine::removeEventHandler(const EntityItemID& entityID, const QStrin · 26 unmodified lines | ||
| 709 | 704 | Q_ARG(const EntityItemID&, entityID), |
| 710 | 705 | Q_ARG(const QString&, eventName), |
| 711 | 706 | Q_ARG(QScriptValue, handler)); |
| 712 | − _hasInvokeMethod.wakeAll(); | |
| 713 | 707 | return; |
| 714 | 708 | } |
| 715 | 709 | #ifdef THREAD_DEBUGGING |
| @@ -741,7 +735,6 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& · 25 unmodified lines | ||
| 741 | 735 | Q_ARG(const EntityItemID&, entityID), |
| 742 | 736 | Q_ARG(const QString&, eventName), |
| 743 | 737 | Q_ARG(QScriptValue, handler)); |
| 744 | − _hasInvokeMethod.wakeAll(); | |
| 745 | 738 | return; |
| 746 | 739 | } |
| 747 | 740 | #ifdef THREAD_DEBUGGING |
| @@ -828,7 +821,6 @@ QScriptValue ScriptEngine::evaluate(const QString& sourceCode, const QString& fi · 80 unmodified lines | ||
| 828 | 821 | Q_ARG(const QString&, sourceCode), |
| 829 | 822 | Q_ARG(const QString&, fileName), |
| 830 | 823 | Q_ARG(int, lineNumber)); |
| 831 | − _hasInvokeMethod.wakeAll(); | |
| 832 | 824 | return result; |
| 833 | 825 | } |
| 834 | 826 | |
| @@ -916,38 +908,11 @@ void ScriptEngine::run() { · 81 unmodified lines | ||
| 916 | 908 | break; |
| 917 | 909 | } |
| 918 | 910 | |
| 919 | − // determine how long before the next timer should fire, we'd ideally like to sleep just | |
| 920 | − // that long, so the next processEvents() will allow the timers to fire on time. | |
| 921 | − const std::chrono::microseconds minTimerTimeRemaining(USECS_PER_MSEC * getTimersRemainingTime()); | |
| 922 | − | |
| 923 | − // However, if we haven't yet slept at least as long as our average timer per frame, then we will | |
| 924 | − // punish the timers to at least wait as long as the average run time of the timers. | |
| 925 | − auto untilTimer = std::max(minTimerTimeRemaining, averageTimerPerFrame); | |
| 926 | − | |
| 927 | − // choose the closest time point, our | |
| 928 | − auto remainingSleepUntil = std::chrono::duration_cast<std::chrono::microseconds>(sleepUntil - clock::now()); | |
| 929 | − auto closestUntil = std::min(remainingSleepUntil, untilTimer); | |
| 930 | − auto thisSleepUntil = std::min(sleepUntil, clock::now() + closestUntil); | |
| 931 | − auto untilThisSleepUntil = std::chrono::duration_cast<std::chrono::microseconds>(thisSleepUntil - clock::now()); | |
| 932 | − | |
| 933 | − // if the sleep until is more than 1 ms away, then don't sleep, and instead use a wait condition | |
| 934 | − // for any possible invoke methods that might also be pending. | |
| 935 | − const std::chrono::microseconds MAX_USECS_TO_SLEEP(USECS_PER_MSEC); | |
| 936 | − if (untilThisSleepUntil < MAX_USECS_TO_SLEEP) { | |
| 937 | − qDebug() << "[" << getFilename() << "]" << "about to sleep untilThisSleepUntil:" << untilThisSleepUntil.count() << "usec -- averageTimerPerFrame:" << averageTimerPerFrame.count(); | |
| 938 | − std::this_thread::sleep_until(thisSleepUntil); | |
| 939 | − } else { | |
| 940 | − // FIXME - we might want to make this 1 less ms to wait | |
| 941 | − unsigned long maxWait = untilThisSleepUntil.count() / USECS_PER_MSEC; | |
| 942 | − qDebug() << "[" << getFilename() << "]" << "about to wait:" << maxWait << "ms --- untilThisSleepUntil:" << untilThisSleepUntil.count() << "usec -- averageTimerPerFrame:" << averageTimerPerFrame.count(); | |
| 943 | − _waitingOnInvokeMethod.lock(); | |
| 944 | − bool signalled = _hasInvokeMethod.wait(&_waitingOnInvokeMethod, maxWait); | |
| 945 | − _waitingOnInvokeMethod.unlock(); | |
| 946 | − if (signalled) { | |
| 947 | − qDebug() << "[" << getFilename() << "]" << "SIGNALLED!! done waiting... now:" << usecTimestampNow(); | |
| 948 | − } | |
| 949 | − | |
| 950 | − } | |
| 911 | + // We only want to sleep a small amount so that any pending events (like timers or invokeMethod events) | |
| 912 | + // will be able to process quickly. | |
| 913 | + static const int SMALL_SLEEP_AMOUNT = 100; | |
| 914 | + auto smallSleepUntil = clock::now() + static_cast<std::chrono::microseconds>(SMALL_SLEEP_AMOUNT); | |
| 915 | + std::this_thread::sleep_until(smallSleepUntil); | |
| 951 | 916 | } |
| 952 | 917 | |
| 953 | 918 | #ifdef SCRIPT_DELAY_DEBUG |
| @@ -1037,21 +1002,6 @@ void ScriptEngine::run() { · 83 unmodified lines | ||
| 1037 | 1002 | emit doneRunning(); |
| 1038 | 1003 | } |
| 1039 | 1004 | |
| 1040 | −quint64 ScriptEngine::getTimersRemainingTime() { | |
| 1041 | − quint64 minimumTime = USECS_PER_SECOND; // anything larger than this can be ignored | |
| 1042 | − QMutableHashIterator<QTimer*, CallbackData> i(_timerFunctionMap); | |
| 1043 | − while (i.hasNext()) { | |
| 1044 | − i.next(); | |
| 1045 | − QTimer* timer = i.key(); | |
| 1046 | − int remainingTime = timer->remainingTime(); | |
| 1047 | − if (remainingTime >= 0) { | |
| 1048 | − minimumTime = std::min((quint64)remainingTime, minimumTime); | |
| 1049 | − } | |
| 1050 | − } | |
| 1051 | − return minimumTime; | |
| 1052 | −} | |
| 1053 | − | |
| 1054 | − | |
| 1055 | 1005 | // NOTE: This is private because it must be called on the same thread that created the timers, which is why |
| 1056 | 1006 | // we want to only call it in our own run "shutdown" processing. |
| 1057 | 1007 | void ScriptEngine::stopAllTimers() { |
| @@ -1062,6 +1012,7 @@ void ScriptEngine::stopAllTimers() { · 4 unmodified lines | ||
| 1062 | 1012 | stopTimer(timer); |
| 1063 | 1013 | } |
| 1064 | 1014 | } |
| 1015 | + | |
| 1065 | 1016 | void ScriptEngine::stopAllTimersForEntityScript(const EntityItemID& entityID) { |
| 1066 | 1017 | // We could maintain a separate map of entityID => QTimer, but someone will have to prove to me that it's worth the complexity. -HRS |
| 1067 | 1018 | QVector<QTimer*> toDelete; |
| @@ -1085,7 +1036,6 @@ void ScriptEngine::stop(bool marshal) { · 17 unmodified lines | ||
| 1085 | 1036 | |
| 1086 | 1037 | if (marshal) { |
| 1087 | 1038 | QMetaObject::invokeMethod(this, "stop"); |
| 1088 | − _hasInvokeMethod.wakeAll(); | |
| 1089 | 1039 | return; |
| 1090 | 1040 | } |
| 1091 | 1041 | if (!_isFinished) { |
| @@ -1106,7 +1056,6 @@ void ScriptEngine::callAnimationStateHandler(QScriptValue callback, AnimVariantM · 14 unmodified lines | ||
| 1106 | 1056 | Q_ARG(QStringList, names), |
| 1107 | 1057 | Q_ARG(bool, useNames), |
| 1108 | 1058 | Q_ARG(AnimVariantResultHandler, resultHandler)); |
| 1109 | − _hasInvokeMethod.wakeAll(); | |
| 1110 | 1059 | return; |
| 1111 | 1060 | } |
| 1112 | 1061 | QScriptValue javascriptParameters = parameters.animVariantMapToScriptValue(this, names, useNames); |
| @@ -1457,7 +1406,6 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co · 344 unmodified lines | ||
| 1457 | 1406 | Q_ARG(const QString&, contents), |
| 1458 | 1407 | Q_ARG(bool, isURL), |
| 1459 | 1408 | Q_ARG(bool, success)); |
| 1460 | − _hasInvokeMethod.wakeAll(); | |
| 1461 | 1409 | return; |
| 1462 | 1410 | } |
| 1463 | 1411 | |
| @@ -1556,7 +1504,6 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID) { · 92 unmodified lines | ||
| 1556 | 1504 | |
| 1557 | 1505 | QMetaObject::invokeMethod(this, "unloadEntityScript", |
| 1558 | 1506 | Q_ARG(const EntityItemID&, entityID)); |
| 1559 | − _hasInvokeMethod.wakeAll(); | |
| 1560 | 1507 | return; |
| 1561 | 1508 | } |
| 1562 | 1509 | #ifdef THREAD_DEBUGGING |
| @@ -1578,7 +1525,6 @@ void ScriptEngine::unloadAllEntityScripts() { · 15 unmodified lines | ||
| 1578 | 1525 | #endif |
| 1579 | 1526 | |
| 1580 | 1527 | QMetaObject::invokeMethod(this, "unloadAllEntityScripts"); |
| 1581 | − _hasInvokeMethod.wakeAll(); | |
| 1582 | 1528 | return; |
| 1583 | 1529 | } |
| 1584 | 1530 | #ifdef THREAD_DEBUGGING |
| @@ -1665,21 +1611,16 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl& · 80 unmodified lines | ||
| 1665 | 1611 | } |
| 1666 | 1612 | |
| 1667 | 1613 | void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) { |
| 1668 | − qDebug() << "[" << getFilename() << "]" << __FUNCTION__ << "method:" << methodName << "now:" << usecTimestampNow(); | |
| 1669 | − | |
| 1670 | 1614 | if (QThread::currentThread() != thread()) { |
| 1671 | 1615 | #ifdef THREAD_DEBUGGING |
| 1672 | 1616 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " |
| 1673 | 1617 | "entityID:" << entityID << "methodName:" << methodName; |
| 1674 | 1618 | #endif |
| 1675 | 1619 | |
| 1676 | − qDebug() << "[" << getFilename() << "]" << "about to invokeMethod callEntityScriptMethod() now:" << usecTimestampNow(); | |
| 1677 | − | |
| 1678 | 1620 | QMetaObject::invokeMethod(this, "callEntityScriptMethod", |
| 1679 | 1621 | Q_ARG(const EntityItemID&, entityID), |
| 1680 | 1622 | Q_ARG(const QString&, methodName), |
| 1681 | 1623 | Q_ARG(const QStringList&, params)); |
| 1682 | − _hasInvokeMethod.wakeAll(); | |
| 1683 | 1624 | return; |
| 1684 | 1625 | } |
| 1685 | 1626 | #ifdef THREAD_DEBUGGING |
| @@ -1695,8 +1636,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 9 unmodified lines | ||
| 1695 | 1636 | QScriptValueList args; |
| 1696 | 1637 | args << entityID.toScriptValue(this); |
| 1697 | 1638 | args << qScriptValueFromSequence(this, params); |
| 1698 | − | |
| 1699 | − qDebug() << "[" << getFilename() << "]" << __FUNCTION__ << "about to callWithEnvironment()... method:" << methodName << "now:" << usecTimestampNow(); | |
| 1700 | 1639 | callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args); |
| 1701 | 1640 | } |
| 1702 | 1641 | |
| @@ -1714,7 +1653,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 11 unmodified lines | ||
| 1714 | 1653 | Q_ARG(const EntityItemID&, entityID), |
| 1715 | 1654 | Q_ARG(const QString&, methodName), |
| 1716 | 1655 | Q_ARG(const PointerEvent&, event)); |
| 1717 | − _hasInvokeMethod.wakeAll(); | |
| 1718 | 1656 | return; |
| 1719 | 1657 | } |
| 1720 | 1658 | #ifdef THREAD_DEBUGGING |
| @@ -1748,7 +1686,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 27 unmodified lines | ||
| 1748 | 1686 | Q_ARG(const QString&, methodName), |
| 1749 | 1687 | Q_ARG(const EntityItemID&, otherID), |
| 1750 | 1688 | Q_ARG(const Collision&, collision)); |
| 1751 | − _hasInvokeMethod.wakeAll(); | |
| 1752 | 1689 | return; |
| 1753 | 1690 | } |
| 1754 | 1691 | #ifdef THREAD_DEBUGGING |