<commit_before>### define
underscore : _
jquery : $
libs/request : Request
libs/event_mixin : EventMixin
libs/toast : Toast
###

class StateLogger

  PUSH_THROTTLE_TIME : 30000 #30s
  SAVE_RETRY_WAITING_TIME : 5000

  constructor : (@flycam, @version, @tracingId, @tracingType, @allowUpdate) ->

    _.extend(this, new EventMixin())
    @mutexedPush = _.mutexDeferred(@pushImpl, -1)

    @newDiffs = []

    # Push state to server whenever a user moves
    @flycam.on
      positionChanged : =>
        @push()


  pushDiff : (action, value, push = true) ->

    @newDiffs.push({
      action : action
      value : value
    })
    # In order to assure that certain actions are atomic,
    # it is sometimes necessary not to push.
    if push
      @push()


  concatUpdateTracing : ->

    throw new Error("concatUpdateTracing has to be overwritten by subclass!")


  #### SERVER COMMUNICATION

  stateSaved : ->

    return @newDiffs.length == 0


  push : ->

    if @allowUpdate
      @pushThrottled()


  pushThrottled : ->
    # Pushes the buffered tracing to the server. Pushing happens at most
    # every 30 seconds.

    @pushThrottled = _.throttle(@mutexedPush, @PUSH_THROTTLE_TIME)
    @pushThrottled()


  pushNow : ->   # Interface for view & controller

    return @mutexedPush(false)


  pushImpl : (notifyOnFailure) ->

    if not @allowUpdate
      return new $.Deferred().resolve().promise()

    # TODO: remove existing updateTracing
    @concatUpdateTracing()

    diffsCurrentLength = @newDiffs.length
    console.log "Sending data: ", @newDiffs
    $.assert(@newDiffs.length > 0, "Empty update sent to server!", {
      @newDiffs
    })

    deferred = $.Deferred()

    Request.sendJSONReceiveJSON(
      "/annotations/#{@tracingType}/#{@tracingId}?version=#{(@version + 1)}"
      method : "PUT"
      data : @newDiffs
    ).then(
      (response) =>
        @newDiffs = @newDiffs.slice(diffsCurrentLength)
        @version = response.version
        @pushDoneCallback()
        deferred.resolve()
      (responseObject) =>
        @pushFailCallback(responseObject, notifyOnFailure)
        deferred.resolve()
    )

    deferred.promise()


  pushFailCallback : (responseObject, notifyOnFailure) ->

    $('body').addClass('save-error')

    if responseObject.responseText? && responseObject.responseText != ""
      # restore whatever is send as the response
      try
        response = JSON.parse(responseObject.responseText)
      catch error
        console.error "parsing failed.", response
      if response?.messages?[0]?.error?
        if response.messages[0].error == "annotation.dirtyState"
          $(window).off("beforeunload")
          alert("""
            It seems that you edited the tracing simultaneously in different windows.
            Editing should be done in a single window only.

            In order to restore the current window, a reload is necessary.
          """)
          window.location.reload()

        else
          Toast.message(response.messages)


    setTimeout((=> @pushNow()), @SAVE_RETRY_WAITING_TIME)
    if notifyOnFailure
      @trigger("pushFailed")


  pushDoneCallback : ->

    @trigger("pushDone")
    $('body').removeClass('save-error')<commit_msg>fixed "annotation.dirtystate" warning not showing up<commit_after>### define
underscore : _
jquery : $
libs/request : Request
libs/event_mixin : EventMixin
libs/toast : Toast
###

class StateLogger

  PUSH_THROTTLE_TIME : 30000 #30s
  SAVE_RETRY_WAITING_TIME : 5000

  constructor : (@flycam, @version, @tracingId, @tracingType, @allowUpdate) ->

    _.extend(this, new EventMixin())
    @mutexedPush = _.mutexDeferred(@pushImpl, -1)

    @newDiffs = []

    # Push state to server whenever a user moves
    @flycam.on
      positionChanged : =>
        @push()


  pushDiff : (action, value, push = true) ->

    @newDiffs.push({
      action : action
      value : value
    })
    # In order to assure that certain actions are atomic,
    # it is sometimes necessary not to push.
    if push
      @push()


  concatUpdateTracing : ->

    throw new Error("concatUpdateTracing has to be overwritten by subclass!")


  #### SERVER COMMUNICATION

  stateSaved : ->

    return @newDiffs.length == 0


  push : ->

    if @allowUpdate
      @pushThrottled()


  pushThrottled : ->
    # Pushes the buffered tracing to the server. Pushing happens at most
    # every 30 seconds.

    @pushThrottled = _.throttle(@mutexedPush, @PUSH_THROTTLE_TIME)
    @pushThrottled()


  pushNow : ->   # Interface for view & controller

    return @mutexedPush(false)


  pushImpl : (notifyOnFailure) ->

    if not @allowUpdate
      return new $.Deferred().resolve().promise()

    # TODO: remove existing updateTracing
    @concatUpdateTracing()

    diffsCurrentLength = @newDiffs.length
    console.log "Sending data: ", @newDiffs
    $.assert(@newDiffs.length > 0, "Empty update sent to server!", {
      @newDiffs
    })

    deferred = $.Deferred()

    Request.sendJSONReceiveJSON(
      "/annotations/#{@tracingType}/#{@tracingId}?version=#{(@version + 1)}"
      method : "PUT"
      data : @newDiffs
    ).then(
      (response) =>
        @newDiffs = @newDiffs.slice(diffsCurrentLength)
        @version = response.version
        @pushDoneCallback()
        deferred.resolve()
      (responseObject) =>
        @pushFailCallback(responseObject, notifyOnFailure)
        deferred.resolve()
    )

    deferred.promise()


  pushFailCallback : (response, notifyOnFailure) ->

    $('body').addClass('save-error')

    if response.messages?[0].error?
      if response.messages[0].error == "Annotation is not up to date. You can't make any changes"
        $(window).off("beforeunload")
        alert("""
          It seems that you edited the tracing simultaneously in different windows.
          Editing should be done in a single window only.

          In order to restore the current window, a reload is necessary.
        """)
        window.location.reload()


    setTimeout((=> @pushNow()), @SAVE_RETRY_WAITING_TIME)
    if notifyOnFailure
      @trigger("pushFailed")


  pushDoneCallback : ->

    @trigger("pushDone")
    $('body').removeClass('save-error')
{'fraction_non_alphanumeric': 0.11584382058728622, 'fraction_numerical': 0.006131010003226848, 'mean_word_length': 2.789119804400978, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2137637', 'n_tokens_mistral': 1943, 'n_tokens_neox': 1812, 'n_words': 469}