<commit_before>package org.cocolab.inpro.incremental.processor;

import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.cocolab.inpro.incremental.unit.EditMessage;
import org.cocolab.inpro.incremental.unit.EditType;
import org.cocolab.inpro.incremental.unit.IU;
import org.cocolab.inpro.incremental.unit.WordIU;

import edu.cmu.sphinx.util.props.PropertyException;
import edu.cmu.sphinx.util.props.PropertySheet;
import edu.cmu.sphinx.util.props.S4Boolean;
import edu.cmu.sphinx.util.props.S4Integer;

public class IUBasedFloorTracker extends AbstractFloorTracker {
	
	@S4Integer(defaultValue = 0)
	public final static String PROP_RISING_TIMEOUT = "risingTimeout";
	private int risingTimeout;
	
	@S4Integer(defaultValue = 700)
	public final static String PROP_ANY_TIMEOUT = "anyProsodyTimeout";
	private int anyProsodyTimeout;
	
	@S4Boolean(defaultValue = true)
	public final static String PROP_USE_PROSODY = "useProsody";
	private boolean useProsody;
	
	private static Logger logger = Logger.getLogger(IUBasedFloorTracker.class);
	
	TimeOutThread timeOutThread;

	/* @see org.cocolab.inpro.incremental.processor.AbstractFloorTracker#newProperties(edu.cmu.sphinx.util.props.PropertySheet) */
	@Override
	public void newProperties(PropertySheet ps) throws PropertyException {
		super.newProperties(ps);
		risingTimeout = ps.getInt(PROP_RISING_TIMEOUT);
		anyProsodyTimeout = ps.getInt(PROP_ANY_TIMEOUT);
		useProsody = ps.getBoolean(PROP_USE_PROSODY);
	}


	/* (non-Javadoc)
	 * @see org.cocolab.inpro.incremental.processor.AbstractFloorTracker#hypChange(java.util.Collection, java.util.List)
	 */
	@Override
	public void hypChange(Collection<? extends IU> ius,
			List<? extends EditMessage<? extends IU>> edits) {
		if (edits != null && edits.size() > 0) {
			logger.debug(edits);			
			if (edits.get(0).getType() == EditType.ADD){
				logger.debug("found an add -- this means that any timeout thread should be killed");
				if (timeOutThread != null)
					timeOutThread.killbit = true;
				timeOutThread = null;
			}
			if (edits.get(edits.size() - 1).getType() == EditType.COMMIT) {
				logger.debug("found a commit!");
				assert timeOutThread == null : "There shall be no timeout threads during speech";
				@SuppressWarnings("unchecked")
				List<WordIU> words = (List<WordIU>) ius;
				assert words.size() > 0 : edits + "" + words;
				WordIU endingWord = words.get(words.size() - 1);
				if (endingWord != null && endingWord.isSilence()) {
					logger.debug("ending word is silence, trying predecessor: " + endingWord);
					endingWord = words.get(words.size() - 2);
				}
				logger.debug("will work with: " + endingWord);
				if (endingWord != null) {
					timeOutThread = new TimeOutThread(endingWord);
					timeOutThread.start();
				}
			}
		}
	}

	
	private class TimeOutThread extends Thread {

		/** if set, this timeout thread will not do anything when its timer runs out */
		boolean killbit = false;
		
		WordIU endingWord;
		
		public TimeOutThread(WordIU endingWord) {
			this.endingWord = endingWord;
		}

		private void sleepSafely(long timeout) {
			if (timeout < 0)
				return;
			logger.debug("going to sleep for " + timeout + " milliseconds");
			try {
				Thread.sleep(risingTimeout);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}<commit_msg>trying to find the reason for okko's weird NullPointerException<commit_after>package org.cocolab.inpro.incremental.processor;

import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.cocolab.inpro.incremental.unit.EditMessage;
import org.cocolab.inpro.incremental.unit.EditType;
import org.cocolab.inpro.incremental.unit.IU;
import org.cocolab.inpro.incremental.unit.WordIU;

import edu.cmu.sphinx.util.props.PropertyException;
import edu.cmu.sphinx.util.props.PropertySheet;
import edu.cmu.sphinx.util.props.S4Boolean;
import edu.cmu.sphinx.util.props.S4Integer;

public class IUBasedFloorTracker extends AbstractFloorTracker {
	
	@S4Integer(defaultValue = 0)
	public final static String PROP_RISING_TIMEOUT = "risingTimeout";
	private int risingTimeout;
	
	@S4Integer(defaultValue = 700)
	public final static String PROP_ANY_TIMEOUT = "anyProsodyTimeout";
	private int anyProsodyTimeout;
	
	@S4Boolean(defaultValue = true)
	public final static String PROP_USE_PROSODY = "useProsody";
	private boolean useProsody;
	
	private static Logger logger = Logger.getLogger(IUBasedFloorTracker.class);
	
	TimeOutThread timeOutThread;

	/* @see org.cocolab.inpro.incremental.processor.AbstractFloorTracker#newProperties(edu.cmu.sphinx.util.props.PropertySheet) */
	@Override
	public void newProperties(PropertySheet ps) throws PropertyException {
		super.newProperties(ps);
		risingTimeout = ps.getInt(PROP_RISING_TIMEOUT);
		anyProsodyTimeout = ps.getInt(PROP_ANY_TIMEOUT);
		useProsody = ps.getBoolean(PROP_USE_PROSODY);
	}


	/* (non-Javadoc)
	 * @see org.cocolab.inpro.incremental.processor.AbstractFloorTracker#hypChange(java.util.Collection, java.util.List)
	 */
	@Override
	public void hypChange(Collection<? extends IU> ius,
			List<? extends EditMessage<? extends IU>> edits) {
		if (edits != null && edits.size() > 0) {
			logger.debug(edits);			
			if (edits.get(0).getType() == EditType.ADD){
				logger.debug("found an add -- this means that any timeout thread should be killed");
				if (timeOutThread != null)
					timeOutThread.killbit = true;
				timeOutThread = null;
			}
			if (edits.get(edits.size() - 1).getType() == EditType.COMMIT) {
				logger.debug("found a commit!");
				assert timeOutThread == null : "There shall be no timeout threads during speech";
				@SuppressWarnings("unchecked")
				List<WordIU> words = (List<WordIU>) ius;
				assert words != null : "hey, if there's a commit, then there must be words!";
				assert words.size() > 0 : edits + "" + words;
				WordIU endingWord = words.get(words.size() - 1);
				if (endingWord != null && endingWord.isSilence()) {
					logger.debug("ending word is silence, trying predecessor: " + endingWord);
					endingWord = words.get(words.size() - 2);
				}
				logger.debug("will work with: " + endingWord);
				if (endingWord != null) {
					timeOutThread = new TimeOutThread(endingWord);
					timeOutThread.start();
				}
			}
		}
	}

	
	private class TimeOutThread extends Thread {

		/** if set, this timeout thread will not do anything when its timer runs out */
		boolean killbit = false;
		/** the word that we'll inspect for rising pitch */
		WordIU endingWord;
		
		public TimeOutThread(WordIU endingWord) {
			this.endingWord = endingWord;
		}

		private void sleepSafely(long timeout) {
			if (timeout < 5) // ignore microsleeps
				return;
			logger.debug("going to sleep for " + timeout + " milliseconds");
			try {
				Thread.sleep(risingTimeout);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
{'fraction_non_alphanumeric': 0.11541260369669626, 'fraction_numerical': 0.004948333575898705, 'mean_word_length': 4.253822629969419, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, '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': '1919181', 'n_tokens_mistral': 2527, 'n_tokens_neox': 2182, 'n_words': 503}