// returns list of resolved files if updated successfully, or null if write action or dumb mode
  // started
  private int[] processFile(
      @NotNull final VirtualFile file, int fileId, @NotNull final ProgressIndicator indicator) {
    final TIntHashSet forward;
    try {
      forward = calcForwardRefs(file, indicator);
    } catch (IndexNotReadyException e) {
      return null;
    } catch (ApplicationUtil.CannotRunReadActionException e) {
      return null;
    } catch (ProcessCanceledException e) {
      throw e;
    } catch (Exception e) {
      log(ExceptionUtil.getThrowableText(e));
      flushLog();
      return null;
    }

    int[] forwardIds = forward.toArray();
    fileIsResolved.set(fileId);
    logf(
        "  ---- " + file.getPresentableUrl() + " processed. forwardIds: " + toVfString(forwardIds));
    for (Listener listener : myListeners) {
      listener.fileResolved(file);
    }
    return forwardIds;
  }
 protected void fireBuildEvent(Status status) {
   synchronized (myListeners) {
     for (Listener l : myListeners) {
       l.onBuildEvent(status);
     }
   }
 }
 protected void fireBookEvent(BookEvent event, Book book) {
   synchronized (myListeners) {
     for (Listener l : myListeners) {
       l.onBookEvent(event, book);
     }
   }
 }
  public Collection<Type> make(API api, Container.Entry entry) {
    Listener listener = getListener(entry);

    if (listener == null) {
      return Collections.emptyList();
    } else {
      return listener.getRootTypes();
    }
  }
  public void fireEvent(Event event) {
    if (event == null) throw new IllegalArgumentException("event == null");
    Set<Listener> set = listeners.get(event.getId());

    if (set != null) {
      for (Listener l : set.toArray(new Listener[set.size()])) {
        l.eventOccured(event);
      }
    }
  }
 /** @param patterned the patterned to set */
 public void setPatterned(final RenderSettings.Patterned patterned) {
   if (patterned.equals(this.patterned)) {
     return;
   }
   this.patterned = patterned.copy();
   if (getSelectedIndex() >= 0) { // něco bylo vybráno, ne text, tak to novu vybrat, ale ponovu
     final int index = urciCoMabytVybrano();
     setSelectedIndex(index);
   }
   for (final Listener listener : listeners) {
     listener.patternChanged(patterned);
   }
 }
  public ErrorCode submitFrame(FrameBuffer bgraFrame) {
    if (this.getIsPaused()) {
      resumeBroadcasting();
    } else if (!this.getIsBroadcasting()) {
      return ErrorCode.TTV_EC_STREAM_NOT_STARTED;
    }

    ErrorCode ret = m_Stream.submitVideoFrame(bgraFrame);

    // if there is a problem when submitting a frame let the client know
    if (ret != ErrorCode.TTV_EC_SUCCESS) {
      String err = ErrorCode.getString(ret);
      if (ErrorCode.succeeded(ret)) {
        reportWarning(String.format("Warning in SubmitTexturePointer: %s\n", err));
      } else {
        reportError(String.format("Error in SubmitTexturePointer: %s\n", err));

        // errors are not recoverable
        stopBroadcasting();
      }

      if (m_Listener != null) {
        m_Listener.onframeSubmissionIssue(ret);
      }
    }

    return ret;
  }
  public void stopCallback(ErrorCode ret) {
    if (ErrorCode.succeeded(ret)) {
      m_VideoParams = null;
      m_AudioParams = null;

      cleanupBuffers();

      try {
        if (m_Listener != null) {
          m_Listener.onBroadcastStopped();
        }
      } catch (Exception x) {
        reportError(x.toString());
      }

      if (m_LoggedIn) {
        setBroadcastState(BroadcastState.ReadyToBroadcast);
      } else {
        setBroadcastState(BroadcastState.Initialized);
      }
    } else {
      // there's not really a good state to go into here
      setBroadcastState(BroadcastState.ReadyToBroadcast);

      String err = ErrorCode.getString(ret);
      reportError(String.format("stopCallback got failure: %s", err));
    }
  }
  /**
   * Logs the current user out and clear the username and auth token. This will terminate the
   * broadcast if necessary.
   */
  public boolean logout() {
    if (getIsIngestTesting()) {
      return false;
    }

    // stop synchronously
    if (this.getIsBroadcasting()) {
      m_Stream.stop(false);
    }

    m_UserName = "";
    m_AuthToken = new AuthToken();

    if (!m_LoggedIn) {
      return false;
    }

    m_LoggedIn = false;

    // only fire the event if the logout was explicitly requested
    if (!m_ShuttingDown) {
      try {
        if (m_Listener != null) {
          m_Listener.onLoggedOut();
        }
      } catch (Exception x) {
        reportError(x.toString());
      }
    }

    setBroadcastState(BroadcastState.Initialized);

    return true;
  }
  public Type make(API api, Container.Entry entry, String fragment) {
    Listener listener = getListener(entry);

    if (listener == null) {
      return null;
    } else {
      if ((fragment != null) && (fragment.length() > 0)) {
        // Search type name in fragment. URI format : see jd.gui.api.feature.UriOpener
        int index = fragment.indexOf('-');

        if (index != -1) {
          // Keep type name only
          fragment = fragment.substring(0, index);
        }

        return listener.getType(fragment);
      } else {
        return listener.getMainType();
      }
    }
  }
  public void getGameNameListCallback(ErrorCode result, GameInfoList list) {
    if (ErrorCode.failed(result)) {
      String err = ErrorCode.getString(result);
      reportError(String.format("GameNameListCallback got failure: %s", err));
    }

    try {
      if (m_Listener != null) {
        m_Listener.onGameNameListReceived(result, list == null ? new GameInfo[0] : list.list);
      }
    } catch (Exception x) {
      reportError(x.toString());
    }
  }
  protected void setBroadcastState(BroadcastState state) {
    if (state == m_BroadcastState) {
      return;
    }

    m_BroadcastState = state;

    try {
      if (m_Listener != null) {
        m_Listener.onBroadcastStateChanged(state);
      }
    } catch (Exception x) {
      reportError(x.toString());
    }
  }
  public void getStreamInfoCallback(ErrorCode result, StreamInfo streamInfo) {
    if (ErrorCode.succeeded(result)) {
      m_StreamInfo = streamInfo;

      try {
        if (m_Listener != null) {
          m_Listener.onStreamInfoUpdated(streamInfo);
        }
      } catch (Exception x) {
        reportError(x.toString());
      }
    } else {
      // String err = ErrorCode.getString(result);
      // reportWarning(String.Format("StreamInfoDoneCallback got failure: {0}", err));
    }
  }
  public void startCallback(ErrorCode ret) {
    if (ErrorCode.succeeded(ret)) {
      try {
        if (m_Listener != null) {
          m_Listener.onBroadcastStarted();
        }
      } catch (Exception x) {
        reportError(x.toString());
      }

      setBroadcastState(BroadcastState.Broadcasting);
    } else {
      m_VideoParams = null;
      m_AudioParams = null;

      setBroadcastState(BroadcastState.ReadyToBroadcast);

      String err = ErrorCode.getString(ret);
      reportError(String.format("startCallback got failure: %s", err));
    }
  }
  public void loginCallback(ErrorCode result, ChannelInfo channelInfo) {
    if (ErrorCode.succeeded(result)) {
      m_ChannelInfo = channelInfo;
      setBroadcastState(BroadcastState.LoggedIn);
      m_LoggedIn = true;
    } else {
      setBroadcastState(BroadcastState.Initialized);
      m_LoggedIn = false;

      String err = ErrorCode.getString(result);
      reportError(String.format("LoginCallback got failure: %s", err));
    }

    try {
      if (m_Listener != null) {
        m_Listener.onLoginAttemptComplete(result);
      }
    } catch (Exception x) {
      reportError(x.toString());
    }
  }
  public void requestAuthTokenCallback(ErrorCode result, AuthToken authToken) {
    if (ErrorCode.succeeded(result)) {
      // Now that the user is authorized the information can be requested about which server to
      // stream to
      m_AuthToken = authToken;
      setBroadcastState(BroadcastState.Authenticated);
    } else {
      m_AuthToken.data = "";
      setBroadcastState(BroadcastState.Initialized);

      String err = ErrorCode.getString(result);
      reportError(String.format("RequestAuthTokenDoneCallback got failure: %s", err));
    }

    try {
      if (m_Listener != null) {
        m_Listener.onAuthTokenRequestComplete(result, authToken);
      }
    } catch (Exception x) {
      reportError(x.toString());
    }
  }
  public void getIngestServersCallback(ErrorCode result, IngestList ingestList) {
    if (ErrorCode.succeeded(result)) {
      m_IngestList = ingestList;

      // assume we're going to use the default ingest server unless overridden by the client
      m_IngestServer = m_IngestList.getDefaultServer();

      setBroadcastState(BroadcastState.ReceivedIngestServers);

      try {
        if (m_Listener != null) {
          m_Listener.onIngestListReceived(ingestList);
        }
      } catch (Exception x) {
        reportError(x.toString());
      }
    } else {
      String err = ErrorCode.getString(result);
      reportError(String.format("IngestListCallback got failure: %s", err));

      // try again
      setBroadcastState(BroadcastState.LoggingIn);
    }
  }
  private void processBatch(
      @NotNull final ProgressIndicator indicator, @NotNull Set<VirtualFile> files) {
    assert !myApplication.isDispatchThread();
    final int resolvedInPreviousBatch = this.resolvedInPreviousBatch;
    final int totalSize = files.size() + resolvedInPreviousBatch;
    final ConcurrentIntObjectMap<int[]> fileToForwardIds =
        ContainerUtil.createConcurrentIntObjectMap();
    final Set<VirtualFile> toProcess = Collections.synchronizedSet(files);
    indicator.setIndeterminate(false);
    ProgressIndicatorUtils.forceWriteActionPriority(indicator, (Disposable) indicator);
    long start = System.currentTimeMillis();
    Processor<VirtualFile> processor =
        file -> {
          double fraction = 1 - toProcess.size() * 1.0 / totalSize;
          indicator.setFraction(fraction);
          try {
            if (!file.isDirectory() && toResolve(file, myProject)) {
              int fileId = getAbsId(file);
              int i = totalSize - toProcess.size();
              indicator.setText(i + "/" + totalSize + ": Resolving " + file.getPresentableUrl());
              int[] forwardIds = processFile(file, fileId, indicator);
              if (forwardIds == null) {
                // queueUpdate(file);
                return false;
              }
              fileToForwardIds.put(fileId, forwardIds);
            }
            toProcess.remove(file);
            return true;
          } catch (RuntimeException e) {
            indicator.checkCanceled();
          }
          return true;
        };
    boolean success = true;
    try {
      success = processFilesConcurrently(files, indicator, processor);
    } finally {
      this.resolvedInPreviousBatch = toProcess.isEmpty() ? 0 : totalSize - toProcess.size();
      queue(toProcess, "re-added after fail. success=" + success);
      storeIds(fileToForwardIds);

      long end = System.currentTimeMillis();
      log(
          "Resolved batch of "
              + (totalSize - toProcess.size())
              + " from "
              + totalSize
              + " files in "
              + ((end - start) / 1000)
              + "sec. (Gap: "
              + storage.gap
              + ")");
      synchronized (filesToResolve) {
        upToDate = filesToResolve.isEmpty();
        log("upToDate = " + upToDate);
        if (upToDate) {
          for (Listener listener : myListeners) {
            listener.allFilesResolved();
          }
        }
      }
    }
  }
 private void fireFileCreated(Document document, PsiFile file) {
   for (Listener listener : myListeners) {
     listener.fileCreated(file, document);
   }
 }
 protected void fireDocumentCreated(@NotNull Document document, PsiFile file) {
   for (Listener listener : myListeners) {
     listener.documentCreated(document, file);
   }
 }
 private void fireOnChangeRemoved() {
   for (Listener listener : myListeners) {
     listener.onChangeRemoved(this);
   }
 }
 void fireOnChangeApplied() {
   for (Listener listener : myListeners) {
     listener.onChangeApplied(this);
   }
 }