private void QueueNewTranslationForDisk(TranslationKeys key, string value)
 {
     lock ( _writeToFileSync )
     {
         _newTranslations[key.GetDictionaryLookupKey()] = value;
     }
 }
        private TranslationJob GetOrCreateTranslationJobFor(TranslationKeys key)
        {
            if (_unstartedJobs.TryGetValue(key.GetDictionaryLookupKey(), out TranslationJob job))
            {
                return(job);
            }

            foreach (var completedJob in _completedJobs)
            {
                if (completedJob.Keys.GetDictionaryLookupKey() == key.GetDictionaryLookupKey())
                {
                    return(completedJob);
                }
            }

            Logger.Current.Debug("Queued translation for: " + key.GetDictionaryLookupKey());

            job = new TranslationJob(key);
            _unstartedJobs.Add(key.GetDictionaryLookupKey(), job);

            CheckThresholds();

            return(job);
        }
        /// <summary>
        /// Translates the string of a UI  text or queues it up to be translated
        /// by the HTTP translation service.
        /// </summary>
        private string TranslateOrQueueWebJobImmediate(object ui, string text, TranslationInfo info, bool supportsStabilization)
        {
            // Get the trimmed text
            text = (text ?? ui.GetText()).Trim();

            // Ensure that we actually want to translate this text and its owning UI element.
            if (!string.IsNullOrEmpty(text) && IsTranslatable(text) && ShouldTranslate(ui) && !IsCurrentlySetting(info))
            {
                info?.Reset(text);

                var textKey = new TranslationKeys(text, !supportsStabilization);

                // if we already have translation loaded in our _translatios dictionary, simply load it and set text
                string translation;
                if (TryGetTranslation(textKey, out translation))
                {
                    QueueNewUntranslatedForClipboard(textKey);

                    if (!string.IsNullOrEmpty(translation))
                    {
                        SetTranslatedText(ui, translation, textKey, info);
                        return(translation);
                    }
                }
                else
                {
                    if (supportsStabilization)
                    {
                        // if we dont know what text to translate it to, we need to figure it out.
                        // this might take a while, so add the UI text component to the ongoing operations
                        // list, so we dont start multiple operations for it, as its text might be constantly
                        // changing.
                        _ongoingOperations.Add(ui);

                        // start a coroutine, that will execute once the string of the UI text has stopped
                        // changing. For all texts except 'story' texts, this will add a delay for exactly
                        // 0.5s to the translation. This is barely noticable.
                        //
                        // on the other hand, for 'story' texts, this will take the time that it takes
                        // for the text to stop 'scrolling' in.
                        try
                        {
                            StartCoroutine(
                                WaitForTextStablization(
                                    ui: ui,
                                    delay: 1.0f,  // 1 second to prevent '1 second tickers' from getting translated
                                    maxTries: 60, // 50 tries, about 1 minute
                                    currentTries: 0,
                                    onMaxTriesExceeded: () =>
                            {
                                _ongoingOperations.Remove(ui);
                            },
                                    onTextStabilized: stabilizedText =>
                            {
                                _ongoingOperations.Remove(ui);

                                if (!string.IsNullOrEmpty(stabilizedText) && IsTranslatable(stabilizedText))
                                {
                                    var stabilizedTextKey = new TranslationKeys(stabilizedText, false);

                                    QueueNewUntranslatedForClipboard(stabilizedTextKey);

                                    info?.Reset(stabilizedText);

                                    // once the text has stabilized, attempt to look it up
                                    if (TryGetTranslation(stabilizedTextKey, out translation))
                                    {
                                        if (!string.IsNullOrEmpty(translation))
                                        {
                                            SetTranslatedText(ui, translation, stabilizedTextKey, info);
                                        }
                                    }
                                    else
                                    {
                                        // Lets try not to spam a service that might not be there...
                                        if (_endpoint != null)
                                        {
                                            if (_consecutiveErrors < Settings.MaxErrors && !Settings.IsShutdown)
                                            {
                                                var job = GetOrCreateTranslationJobFor(stabilizedTextKey);
                                                job.Components.Add(ui);
                                            }
                                        }
                                        else
                                        {
                                            QueueNewUntranslatedForDisk(stabilizedTextKey);
                                        }
                                    }
                                }
                            }));
                        }
                        catch (Exception)
                        {
                            _ongoingOperations.Remove(ui);
                        }
                    }
                    else
                    {
                        if (!_startedOperationsForNonStabilizableComponents.Contains(textKey.GetDictionaryLookupKey()))
                        {
                            _startedOperationsForNonStabilizableComponents.Add(textKey.GetDictionaryLookupKey());

                            QueueNewUntranslatedForClipboard(textKey);

                            // Lets try not to spam a service that might not be there...
                            if (_endpoint != null)
                            {
                                if (_consecutiveErrors < Settings.MaxErrors && !Settings.IsShutdown)
                                {
                                    GetOrCreateTranslationJobFor(textKey);
                                }
                            }
                            else
                            {
                                QueueNewUntranslatedForDisk(textKey);
                            }
                        }
                    }
                }
            }

            return(null);
        }
 private bool TryGetTranslation(TranslationKeys key, out string value)
 {
     return(_translations.TryGetValue(key.GetDictionaryLookupKey(), out value));
 }
 private void QueueNewUntranslatedForDisk(TranslationKeys key)
 {
     _newUntranslated.Add(key.GetDictionaryLookupKey());
 }
 private void AddTranslation(TranslationKeys key, string value)
 {
     _translations[key.GetDictionaryLookupKey()] = value;
     _translatedTexts.Add(value);
 }