![]() |
AW: FastSwitch
Zitat:
So schnell wie man dann die Plugins läd können diese sich gar nicht initialisieren. Also der User würde in dem Fall gar nicht sehen was er da laden bzw. in dem Moment für ein Plugin erwischt. Das ist auch der grund warum man unter Winamp diese aus einer Liste unter Konfiguration wählen muss. Ein umschalten zur Laufzeit ist gar nicht möglich. Werde da wohl dann nichts ändern wenn die Anwendung meinen Wrapper so missbrauchen will dann ist es letztendlich nicht mein Problem da in diesem Fall die Handhabung nicht durchdacht ist. gruss |
AW: FastSwitch
Zitat:
|
AW: FastSwitch
Zitat:
Also wäre eine Erklärung oder Referenz angebrachter als der Hinweis, dass das geht und eigentlich recht einfach ist. ;) Eine Erklärung / Referenz hätte ich auf die Schnelle aber auch adhoc nicht an der Hand |
AW: FastSwitch
Zitat:
Aber ich kann nicht von irgend jemand erwarten das er für mich code schreibt. Daher muss ich es im Moment leider so belassen auch wenn es mich stört. Ich muss erst mal schauen ob es ein Beispiel im Net gibt wo ich das mal schritt für schritt beim debuggen verfolgen kann. das ist meine Lernmethode ;) Er hat mir ja freundlicher weise den weg gezeigt nur ich kann es nicht nachvollziehen weil es Anhaltspunkte sind. Das ist mein Thread
Delphi-Quellcode:
Dieser wird beendet über
function SoVisThread(glCtrl: PLongWord): DWORD;
//... nur nötiger teil repeat MsgReturn := GetMessage(Msg, 0, 0, 0); if ((Msg.message = WM_QUIT) or (Msg.message = WM_CLOSE)) then VisualizerQuitted := True else if Msg.message = DataReadyMsg then begin case Msg.wParam of DataReady: BassSoVis.SoRender(glCtrl^); RequestRestFlag: begin p1 := VisDataPointer; inc(p1, 70); p1^ := 0; end; end; end; TranslateMessage(Msg); DispatchMessage(Msg); until (integer(MsgReturn) <= 0) or VisualizerQuitted; end else PostMessage(BassSoVis.MessageHandle, DataReadyMsg, StartVisOut, 0); RenderThreadId := 0; Result := 0; ExitThread(0); end;
Delphi-Quellcode:
gruss
procedure TBASSSoVis.BassSonVisStop;
begin EndByProgram := True; if (RenderThreadId <> 0) then begin PostThreadMessage(RenderThreadId, WM_QUIT, 0, 0); repeat Sleep(15); WinProcessMessages; until RenderThreadId = 0; end else BassSoVisFree := True; end; Hier warte ich dann solange bis die RenderThreadId = 0 ist. Also der Thread beim beenden diese auf 0 gesetzt hat. nur beim schalten in Millisekunden Bereich funktioniert das nicht. Auch das entfernen von Sleep(15) macht keinen unterschied. Der Thread läuft noch während die anderen gestartet wurden. gruss |
AW: FastSwitch
Zitat:
@Emil: Anstatt per sleep und in einer Repeat/Until-Schreife zu warten, bis der Thread fertig ist, kann man das auch über ein Event lösen: Du sagst dem Thread 'Hör auf' (per Message, wie gehabt) und wartest einfach ('WaitForSingleObject'), bis der Thread als letztes das Event setzt ('SetEvent'). Mein Beispielcode zeigt ja nur einen 'Workerthread', der also einfach wartet, bis es etwas zu tun gibt. Du machst etwas ähnliches, und zwar, indem Du dem Thread Messages schickst. Deine Plugin-Threads würde ich auch gar nicht mehr anfassen wollen. Es geht ja hier um eine Konfiguration, die nicht ruckeln soll, wenn ein Plugin geladen/entladen wird. Packe also deine Lade/Beendenlogik in einen Thread, der genau diese beiden Dinge tut (Altes Plugin entladen, Neues laden). |
AW: FastSwitch
Zitat:
Jo genau das habe ich ja gemacht. ![]()
Delphi-Quellcode:
Aber es nutzt nichts.
hEvent := CreateEvent(nil, True, False, nil);
PostThreadMessage(RenderThreadId, WM_QUIT, 0, hEvent); WaitRe := WaitForSingleObject(hEvent, 1000); CloseHandle(hEvent); SetEvent(Msg.LParam); Das nächste Plugin wird dann schon gestartet bevor der Thread überhaupt signalisieren kann. Bei normalen starts signalisiert das Event und der Thread wird rechtzeitig beendet. Aber nicht wenn die Plugins im MS Bereich geändert werden. Anwendung / Mein Wrapper mit dem Thread (DLL) Plugins werden dann damit geladen wenn von der Anwendung angefordert. Die Anwendung fordert das so schnell an das mein Thread da nicht mehr mitkommt. Sah dann so aus
Delphi-Quellcode:
Das einzige was jetzt noch sein könnte..
procedure TBASSSoVis.BassSonVisStop;
var hEvent, WaitRe: DWord; begin EndByProgram := True; if (RenderThreadId <> 0) then begin hEvent := CreateEvent(nil, True, False, nil); PostThreadMessage(RenderThreadId, WM_QUIT, 0, hEvent); WaitRe := WaitForSingleObject(hEvent, 1000); CloseHandle(hEvent); if WaitRe = WAIT_OBJECT_0 then RenderThreadId := 0; end else BassSoVisFree := True; end; BassSonVisStop kein Teil vom aktuellen Thread ist. So wird der Thread erstellt.
Delphi-Quellcode:
SOThreadHandle := BeginThread(nil, 0, @SoVisThread,
@BassSoVis.glCtrl, 0, RenderThreadId); Zitat:
Wenn du die AV damit meinst dann magst du recht haben. gruss |
AW: FastSwitch
Zitat:
Delphi-Quellcode:
Ich habe das Event-Handle global deklariert, damit es vom Thread in jedem Fall verwendet wird und nicht nur dann, wenn es per Message übergeben wurde. Außerdem wartet 'WaitforSingleObject' jetzt solange, bis der Thread fertig ist.
Program Project2;
{$APPTYPE CONSOLE} Uses SysUtils, Windows, messages; Var WaitRe, RenderThreadId, hEvent: Cardinal; Function SoVisThread(glCtrl: PLongWord): DWORD; Var MsgReturn: LongBool; Msg: tagMSG; VisualizerQuitted: Boolean; Begin VisualizerQuitted := False; Repeat write('Thread loop'); MsgReturn := GetMessage(Msg, 0, 0, 0); If ((Msg.message = WM_QUIT) Or (Msg.message = WM_CLOSE)) Then Begin Writeln('*** close received. set Event '); VisualizerQuitted := true; End; TranslateMessage(Msg); DispatchMessage(Msg); Until (integer(MsgReturn) <= 0) or VisualizerQuitted; SetEvent(hEvent); RenderThreadId := 0; Result := 0; Writeln('Thread finished'); ExitThread(0); End; Begin hEvent := CreateEvent(Nil, True, False, Nil); BeginThread(Nil, 0, @SoVisThread, Nil, 0, RenderThreadId); Writeln('Thread created. Press ENTER to stop the thread'); ReadLn; PostThreadMessage(RenderThreadId, WM_QUIT, 0, 0); Writeln('Close signalled, waiting for event'); WaitRe := WaitForSingleObject(hEvent, INFINITE); CloseHandle(hEvent); writeln('Done (Press ENTER to terminate)'); ReadLn; End. |
AW: FastSwitch
Danke für deine Arbeit..
Werde das mal testen und bescheid geben. Ja so geht es bei mir auch ;) Aber nicht wenn ich meinen Thread wenn er noch läuft in Millisekunden Takt erneut aufrufe. PageUP/Down taste.. gruss |
AW: FastSwitch
Zitat:
|
AW: FastSwitch
Zitat:
habe ich genau das getan was du mir gezeigt hast siehe einige Post vorher. Deshalb bin ich auch irgendwie jetzt leicht daneben warum ich immer noch im Thread herum werkle während das nächste schon am laden ist. Das Timing in Millisekunden funktioniert einfach nicht. Das ist mein Problem. Vielleicht versteht man mein Problem auch nicht richtig oder hab mich falsch ausgedrückt. 1. Start der Anwendung = 1 Plugin wird gestartet 2. PageUP wird gedrückt Plugin wird freigegeben über die API BASSVIS_IsFree in Free wird nun mit BassSonVisStop der Thread gestoppt das Plugin entladen und die Resourcen freigegeben. 3. Während das Plugin in Free noch freigegeben wird kommt das nächste von der Anwendung über BASSVIS_ExecutePlugin 4. Ist bis dahin der Thread noch nicht beendet kommt es zu Problemen weil dann das Alte noch entladen wird. VisInfo ist dann nicht mehr identisch mit dem das geladen/entladen wird. Es kommt also unweigerlich zu Kuddelmuddel. Bei normaler Verwendung geschieht das nicht nur wenn der Thread mit dem Timing nicht zurecht kommt. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz