#include-Once
; #INDEX# =======================================================================================================================
; Title .........: paralelFunc
; AutoIt Version : 3.3.14++
; Language ......: Russian
; Description ...: Function for parallel execution of functions
; Author(s) .....: mef-t
; ===============================================================================================================================

Const $controlParam = '__paralelFunc'

; ===============================================================================================================================
; #FUNCTION# ====================================================================================================================
; Name...........: __paralelFunc_Init
; Description ...: Инициирует работу распаралеливания функций
; Syntax.........: __paralelFunc_Init()
; Parameters ....:
; Return values .:
; Author ........: mef-t
; Modified.......:
; Remarks .......: функцию необходимо указывать в самом начале скипта. Все, что указано до функции, будет выполняться вместе с распараллеленой функцией
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __paralelFunc_Init()
	__paralelFunc()
EndFunc

; #FUNCTION# ====================================================================================================================
; Name...........: __paralelFunc
; Description ...: запуск параллельных функций с указанием количества запусков
; Syntax.........: __paralelFunc($function, $count)
; Parameters ....: $function - имя функции без скобок
;                  $count    - количество запусков (по умолчанию 2)
;                  $wait     - 1-ждать завершения, 0-не ждать
; Return values .: массив значений, если $wait = 1
; Author ........: mef-t
; Modified.......:
; Remarks .......: функция запускается без параметров
; Related .......:
; Link ..........:
; Example .......: __paralelFunc('_msg', 5)
; ===============================================================================================================================
Func __paralelFunc($function = Default, $count = 2, $wait = 0)

	If StringInStr($CmdLineRaw, $controlParam) > 0 Then ;запуск по параметру (паралельный запуск фунций)
		$function = StringRegExp($CmdLineRaw, '__paralelFunc (\S+)', 1)
		$function = $function[0]
		Call($function)
		Exit ;выход после выполнения функции
	EndIf

	If $function=Default Then Return
	$Param = $controlParam & ' ' & $function

	Local $iPID[$count]

	$exp = StringRegExp(@ScriptName, '\.(.*)', 1)
	For $i=1 To $count
		If $exp[0] = 'exe' Then
			$iPID[$i-1] = Run('"' & @AutoItExe & '" ' & $Param, '', @SW_HIDE)
		Else
			$iPID[$i-1] = Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & @ScriptFullPath & '"' & ' ' & $Param, '', @SW_HIDE, 0x2)
		EndIf
	Next

	If $wait = 1 Then
		Return __paralelFunc_Wait($iPID)
	EndIf

EndFunc


; #FUNCTION# ====================================================================================================================
; Name...........: __paralelFunc_Wait
; Description ...: ожидание STDUot ответа
; Syntax.........: __paralelFunc_Wait(ByRef $iPID)
; Parameters ....: $iPID - массив PID процессов
; Return values .:
; Author ........: mef-t
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __paralelFunc_Wait(ByRef $iPID)

	Local $count = UBound($iPID)
	Local $aOutput[$count], $aSTD[$count]
	Local $sErr = 0
	Dim $aResult[1]

	While 1

		For $i=0 To $count-1
			If $aSTD[$i] = '' Then
				$aOutput[$i] = StdoutRead($iPID[$i])
				If @error Then
					$aSTD[$i] = 1
					$sErr += 1
				EndIf

			EndIf
		Next
		If $sErr = $count Then ExitLoop

		For $i=0 To $count-1
			If $aOutput[$i] <> '' Then
				ConsoleWrite($aOutput[$i] & @CRLF)
;~ 				ConsoleWrite($iPID[$i] & ' = ' & $aOutput[$i] & @CRLF)
				ReDim $aResult[UBound($aResult)+1]
				$aResult[UBound($aResult)-1] = $aOutput[$i]
				$aResult[0] += 1
			EndIf
		Next
	WEnd

	Return $aResult

EndFunc