"Multithreading" mit Gui

11/22/2010 16:29 lolkop#1
Da immer wieder leute fragen, ob es möglich ist mehrere funktionen nebeneinander her laufen zu lassen, und ich zu faul bin ein tutorial zu schreiben, hier mal ein kleiner beispiel code der allgemein immer funktionieren sollte:
da auch sleeps nutzbar sein sollen, ohne dabei das script zu blockieren, habe ich mir mal ein system ausgedacht, dass die zum jeweiligen "thread" gehörigen aktionen durchnummeriert, und so sleeps per timer einzeln steuern kann

hierbei handelt es sich natürlich nicht um echtes multithreading. alles läuft in einem thread, wird jedoch ohne jegliche script blockierungen "gleichzeitig" ausgeführt.

die activation funktion ist zuständig für das starten und stopen der "threads". habe mal gleich noch mit eingebaut, dass sie auch in der lage ist controls zu bearbeiten (zb button texte ändern auf start/stop).

bei den funktionen und sleeps steht $action für die jeweilige thread bezeichnung.

hier mal ein beispiel, wodurch das ganze hoffentlich klar wird:
wir man hierran erkennt, laufen die einzelnen "threads" in sich nacheinander ab, aber global nebeneinander her.
11/22/2010 17:39 mipez#2
Erklärt sich eigentlich von selbst, von daher muss ein Tut auch nich sein.
Man könnte vielleicht noch eine Funktion einfügen, um die einzelnen Sektionen zu überbrücken/aufzuteilen, ist aber eher Schnickschnack.

Vote 4 Sticky
11/22/2010 17:57 ZeraPain#3
sowas ist meiner meinung nach mit autoit sinnlos.
"multithreading" braucht man nicht wirklich für das, was mit autoit möglich ist.
11/22/2010 20:15 mipez#4
Quote:
Originally Posted by ZeraPain View Post
sowas ist meiner meinung nach mit autoit sinnlos.
"multithreading" braucht man nicht wirklich für das, was mit autoit möglich ist.
Ich sag mal einfach Doodle Jump und Musicplayer;D
11/22/2010 20:19 ZeraPain#5
Doodle Jump -> sagt mir nix
Musicplayer -> bau ich dir auch ohne "multithreading" :)
11/23/2010 16:17 mipez#6
Quote:
Originally Posted by ZeraPain View Post
Doodle Jump -> sagt mir nix
Musicplayer -> bau ich dir auch ohne "multithreading" :)
Will ich sehen, ohne dass dir nach 1 Lied der Replay-Button abschmiert ;D
11/23/2010 16:54 ZeraPain#7
Quote:
Originally Posted by mipez View Post
Will ich sehen, ohne dass dir nach 1 Lied der Replay-Button abschmiert ;D
könnte man noch stark verbessern aber als bsp sollte es mal reichen ;-)

Code:
#include <file.au3>
#include <array.au3>
#include <guilistview.au3>
#include <sound.au3>

Global $path = @ScriptDir
Global $playindex = -1, $playid
Global $timer, $musicinfo, $maxplay
Global $pause = False
Global $OLD_pos

$Form1 = GUICreate("Musicplayer", 450, 200)
$GUI_listview = GUICtrlCreateListView("Play|Filename|Title|Interpret|Duration", 10, 10, 430, 100)
$GUI_pre = GUICtrlCreateButton("<<", 10, 120, 50)
$GUI_next = GUICtrlCreateButton(">>", 60, 120, 50)
$GUI_play = GUICtrlCreateButton("Play", 120, 120, 50)
$GUI_stop = GUICtrlCreateButton("Stop", 170, 120, 50)
$GUI_pause = GUICtrlCreateButton("Pause", 230, 120, 50)
$DISP_pos = GUICtrlCreateLabel("00:00:00", 300, 120, 50)
$GUI_pos = GUICtrlCreateSlider(10, 150, 430, 20)

$array = _FileListToArray($path, "*mp3")
$maxplay = $array[0]
Dim $musicinfo[$maxplay + 1][5]

For $i = 1 To $maxplay
	$info = _FileInfoExtended($path & "\" & $array[$i])
	$infotime = StringSplit($info[1][21], ":")

	$musicinfo[$i][0] = $array[$i] ;Filename
	$musicinfo[$i][1] = $info[1][16] ;Interpret
	$musicinfo[$i][2] = $info[1][10] ;Title
	$musicinfo[$i][3] = $info[1][21] ;Duration
	$musicinfo[$i][4] = ($infotime[1] * 3600 + $infotime[2] * 60 + $infotime[3]) * 1000 ;Duration in ms
	GUICtrlCreateListViewItem("|" & $musicinfo[$i][0] & "|" & $musicinfo[$i][1] & "|" & $musicinfo[$i][2] & "|" & $musicinfo[$i][3], $GUI_listview)
Next

GUISetState()

While 1
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $GUI_play
			$name = _GUICtrlListView_GetItemText($GUI_listview, Int(ControlListView($Form1, "", $GUI_listview, "GetSelected")), 1)
			$playindex = _ArraySearch($array, $name)
			_play($playindex)
		Case $GUI_stop
			_stop()
		Case $GUI_pause
			_pause()
		Case $GUI_next
			_next()
		Case $GUI_pre
			_pre()
	EndSwitch

	If $playindex <> -1 Then
		If TimerDiff($timer) > $musicinfo[$playindex][4] Then _next()
		$sound_per = Int(TimerDiff($timer) / $musicinfo[$playindex][4] * 100)
		If $sound_per <> GUICtrlRead($GUI_pos) Then GUICtrlSetData($GUI_pos, $sound_per)
		If _SoundPos($playid) <> $OLD_pos Then
			$OLD_pos = _SoundPos($playid)
			GUICtrlSetData($DISP_pos, _SoundPos($playid))
		EndIf
	EndIf
WEnd

Func _play($vPlayindex)
	_SoundStop($playid)
	$playid = _SoundOpen($path & "\" & $array[$vPlayindex])
	_playindex($vPlayindex)
	_SoundPlay($playid, 0)
	$timer = TimerInit()
EndFunc   ;==>_play

Func _stop()
	_SoundStop($playid)
EndFunc   ;==>_stop

Func _pause()
	If $pause = False Then
		$pause = True
		_SoundPause($playid)
		GUICtrlSetData($GUI_pause, "Resume")
	Else
		$pause = False
		_SoundResume($playid)
		GUICtrlSetData($GUI_pause, "Pause")
	EndIf
EndFunc   ;==>_pause

Func _next()
	If $playindex > $array[0] Then $playindex = 1
	If $playindex <> -1 Then
		$playindex += 1
		_play($playindex)
	EndIf
EndFunc   ;==>_next

Func _pre()
	If $playindex > $array[0] Then $playindex = 1
	If $playindex <> -1 Then
		$playindex -= 1
		_play($playindex)
	EndIf
EndFunc   ;==>_pre

Func _playindex($iPlay)
	For $i = 0 To $maxplay - 1
		If $i <> $iPlay - 1 Then
			_GUICtrlListView_SetItemText($GUI_listview, $i, "")
		Else
			_GUICtrlListView_SetItemText($GUI_listview, $i, ">")
		EndIf
	Next
EndFunc   ;==>_playindex

Func _FileInfoExtended($FolderOrFile)
	If Not FileExists($FolderOrFile) Then Return SetError(1)
	Local $objShell = ObjCreate("Shell.Application")
	Local $arrHeaders[34], $Type = 'F'
	If StringInStr(FileGetAttrib($FolderOrFile), 'D') Then
		Local $objFolder = $objShell.Namespace($FolderOrFile)
		$Type = 'D'
	Else
		Local $objFSO = ObjCreate("Scripting.FileSystemObject")
		Local $objFile = $objFSO.GetFile($FolderOrFile)
		Local $FileName = $objFSO.GetFileName($objFile)
		Local $objFolder = $objShell.Namespace($objFSO.GetParentFolderName($objFile))
	EndIf
	Local $arRet[1][34]
	For $i = 0 To 33
		$arrHeaders[$i] = $objFolder.GetDetailsOf($objFolder.Items, $i)
		$arRet[0][$i] = $arrHeaders[$i]
	Next
	For $strFileName In $objFolder.Items
		If $Type = 'F' And $objFolder.GetDetailsOf($strFileName, 0) <> $FileName Then ContinueLoop
		ReDim $arRet[UBound($arRet) + 1][34]
		For $i = 0 To 33
			$arRet[UBound($arRet) - 1][$i] = $objFolder.GetDetailsOf($strFileName, $i)
		Next
	Next
	Return $arRet
EndFunc   ;==>_FileInfoExtended
11/23/2010 18:41 mipez#8
Replay bedeutet, dass im Lied1 zu einem festgelegten Zeitpunkt entweder Lied1 oder Lied2 eingespielt wird. Zeitpunkt wird durch das Lied selbst festgelegt.

Aber geht sehr ins OT.

Anderes Beispiel: Downloader ;D
11/23/2010 19:15 ZeraPain#9
Quote:
Originally Posted by mipez View Post
Replay bedeutet, dass im Lied1 zu einem festgelegten Zeitpunkt entweder Lied1 oder Lied2 eingespielt wird. Zeitpunkt wird durch das Lied selbst festgelegt.

Aber geht sehr ins OT.

Anderes Beispiel: Downloader ;D
das mit dem song einspielen kriegt man auch hin.
man kann ja 2 songs parallel laufen lassen. (müsste man nur mehr playid's erstellen)

Downloader.. was genau meinst du jetzt damit?^^
einfach irgendeine datei herunterladen oder wie?
soll ich dir hier jetzt für jedes beispiel was coden ? xD
11/24/2010 17:27 PenGuin :O#10
Downloader?

Pseudocode:

Code:
InetGet(xxx)

;Alles was man zeitgleich machen will hier runter
11/24/2010 19:24 mipez#11
Quote:
Originally Posted by pinguin94 View Post
Downloader?

Pseudocode:

Code:
InetGet(xxx)

;Alles was man zeitgleich machen will hier runter
InetGet lässt sich doch nur 1x parallel ausführen (bei mehr als 1x lädts bei mir nix, ja Parameter wurden richtig bestimmt xD) oô
11/24/2010 22:50 PenGuin :O#12
Ach so meinst du das.
Notfalls InetGet auslagern auf andere Scripte?
11/25/2010 18:49 mipez#13
Quote:
Originally Posted by pinguin94 View Post
Ach so meinst du das.
Notfalls InetGet auslagern auf andere Scripte?
*hust* 16 Scripte am Laufen? *hust* xD
Naja, vllt bringts mit AutoIt nich allzuviel, aber das Prinzip lässt sich wunderbar auf Java übertragen :D
11/25/2010 23:15 MrSm!th#14
java hat meines wissens sowieso multi threading o.ô
11/26/2010 15:48 mipez#15
Quote:
Originally Posted by MrSm!th View Post
java hat meines wissens sowieso multi threading o.ô
Hab das erst seit knapp 2h Arbeitsstunden am Laufen... bis jetzt is mir dazu noch nix aufgefallen (wird alles nacheinander abgearbeitet)...