<commit_before>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

public abstract class HoldableHandler : ICommandResponder
{
	public HoldableHandler(KMHoldableCommander commander, FloatingHoldable holdable, IRCConnection connection, CoroutineCanceller canceller)
	{
		HoldableCommander = commander;
		Holdable = holdable;
		ircConnection = connection;
		Canceller = canceller;
	}

	public IEnumerator RespondToCommand(string userNickName, string message, ICommandResponseNotifier responseNotifier, IRCConnection connection)
	{
		ResponseNotifier = responseNotifier;

		FloatingHoldable.HoldStateEnum holdState = Holdable.HoldState;

		if (holdState == FloatingHoldable.HoldStateEnum.Held)
		{}
		else
		{
			IEnumerator holdCoroutine = HoldableCommander.Hold();
			while (holdCoroutine.MoveNext())
			{
				yield return holdCoroutine.Current;
			}
		}

		IEnumerator processCommand = RespondToCommandCommon(message);
		if (processCommand == null || !processCommand.MoveNext())
		{	
			DebugHelper.Log("Running RespondToCommandInternal()");
			processCommand = RespondToCommandInternal(message);
			bool cancelled = false;
			bool parseError = false;
			bool cancelling = false;
			processIEnumerators.Push(processCommand);
			do
			{
				try
				{
					bool result = false;
					while(!result && processIEnumerators.Count > 0)
					{
						if (processIEnumerators.Count > 0)
							processCommand = processIEnumerators.Pop();
						result = processCommand.MoveNext();
						if (result)
							processIEnumerators.Push(processCommand);
					}
					if (!result) break;
				}
				catch (Exception ex)
				{
					DebugHelper.LogException(ex, "Error Processing command due to an exception. Invocation will not continue.:");
				}
				switch (processCommand.Current)
				{
					case IEnumerator iEnumerator:
						if(iEnumerator != null)
							processIEnumerators.Push(iEnumerator);
						continue;
					case KMSelectable kmSelectable when kmSelectable != null:
						if (heldSelectables.Contains(kmSelectable))
						{
							DebugHelper.Log("Ending Interaction");
							DoInteractionEnd(kmSelectable);
							heldSelectables.Remove(kmSelectable);
						}
						else
						{
							DebugHelper.Log("Starting Interaction");
							DoInteractionStart(kmSelectable);
							heldSelectables.Add(kmSelectable);
						}
						continue;

					case KMSelectable[] kmSelectables:
						foreach (KMSelectable selectable in kmSelectables)
						{
							selectable?.OnInteract?.Invoke();
							selectable?.OnInteractEnded?.Invoke();
							yield return new WaitForSeconds(0.1f);
						}
						continue;

					case Quaternion quaternion:
						HoldableCommander.RotateByLocalQuaternion(quaternion);
						break;

					case string currentString:
						if (currentString.Equals("parseerror", StringComparison.InvariantCultureIgnoreCase))
						{
							ircConnection.SendMessage($"Sorry @{userNickName}, there was an error parsing the command for !{HoldableCommander.ID}");
							parseError = true;
						}
						else if (currentString.Equals("trycancel", StringComparison.InvariantCultureIgnoreCase) &&
						         Canceller.ShouldCancel)
						{
							Canceller.ResetCancel();
							cancelled = true;
						}
						else if (currentString.StartsWith("sendtochat ", StringComparison.InvariantCultureIgnoreCase) &&
						         currentString.Substring(11).Trim() != string.Empty)
						{
							SendToChat(currentString, userNickName);
						}
						else if (currentString.StartsWith("sendtochaterror ", StringComparison.InvariantCultureIgnoreCase) &&
						         currentString.Substring(16).Trim() != string.Empty)<commit_msg>Fix KMSelectable handling on Holdables<commit_after>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

public abstract class HoldableHandler : ICommandResponder
{
	public HoldableHandler(KMHoldableCommander commander, FloatingHoldable holdable, IRCConnection connection, CoroutineCanceller canceller)
	{
		HoldableCommander = commander;
		Holdable = holdable;
		ircConnection = connection;
		Canceller = canceller;
	}

	public IEnumerator RespondToCommand(string userNickName, string message, ICommandResponseNotifier responseNotifier, IRCConnection connection)
	{
		ResponseNotifier = responseNotifier;

		FloatingHoldable.HoldStateEnum holdState = Holdable.HoldState;

		if (holdState == FloatingHoldable.HoldStateEnum.Held)
		{}
		else
		{
			IEnumerator holdCoroutine = HoldableCommander.Hold();
			while (holdCoroutine.MoveNext())
			{
				yield return holdCoroutine.Current;
			}
		}

		IEnumerator processCommand = RespondToCommandCommon(message);
		if (processCommand == null || !processCommand.MoveNext())
		{	
			DebugHelper.Log("Running RespondToCommandInternal()");
			processCommand = RespondToCommandInternal(message);
			bool cancelled = false;
			bool parseError = false;
			bool cancelling = false;
			processIEnumerators.Push(processCommand);
			do
			{
				try
				{
					bool result = false;
					while(!result && processIEnumerators.Count > 0)
					{
						if (processIEnumerators.Count > 0)
							processCommand = processIEnumerators.Pop();
						result = processCommand.MoveNext();
						if (result)
							processIEnumerators.Push(processCommand);
					}
					if (!result) break;
				}
				catch (Exception ex)
				{
					DebugHelper.LogException(ex, "Error Processing command due to an exception. Invocation will not continue.:");
				}
				switch (processCommand.Current)
				{
					case IEnumerator iEnumerator:
						if(iEnumerator != null)
							processIEnumerators.Push(iEnumerator);
						continue;
					case KMSelectable kmSelectable when kmSelectable != null:
						if (heldSelectables.Contains(kmSelectable))
						{
							DoInteractionEnd(kmSelectable);
							heldSelectables.Remove(kmSelectable);
						}
						else
						{
							DoInteractionStart(kmSelectable);
							heldSelectables.Add(kmSelectable);
						}
						break;

					case KMSelectable[] kmSelectables:
						foreach (KMSelectable selectable in kmSelectables)
						{
							if (selectable != null)
							{
								yield return DoInteractionClick(selectable);
							}
							else
							{
								yield return new WaitForSeconds(0.1f);
							}
						}
						break;

					case Quaternion quaternion:
						HoldableCommander.RotateByLocalQuaternion(quaternion);
						break;

					case string currentString:
						if (currentString.Equals("parseerror", StringComparison.InvariantCultureIgnoreCase))
						{
							ircConnection.SendMessage($"Sorry @{userNickName}, there was an error parsing the command for !{HoldableCommander.ID}");
							parseError = true;
						}
						else if (currentString.Equals("trycancel", StringComparison.InvariantCultureIgnoreCase) &&
						         Canceller.ShouldCancel)
						{
							Canceller.ResetCancel();
							cancelled = true;
						}
						else if (currentString.StartsWith("sendtochat ", StringComparison.InvariantCultureIgnoreCase) &&
						         currentString.Substring(11).Trim() != string.Empty)
						{
							SendToChat(currentString, userNickName);
						}
						else if (currentString.StartsWith("sendtochaterror ", StringComparison.InvariantCultureIgnoreCase) &&
						         currentString.Substring(16).Trim() != string.Empty)
{'fraction_non_alphanumeric': 0.08907928736570107, 'fraction_numerical': 0.002175982592139263, 'mean_word_length': 3.408872901678657, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '1081091', 'n_tokens_mistral': 2864, 'n_tokens_neox': 2054, 'n_words': 412}