Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   FastSwitch (https://www.delphipraxis.net/178190-fastswitch.html)

Furtbichler 26. Dez 2013 21:24

AW: FastSwitch
 
Zitat:

Zitat von EWeiss (Beitrag 1241114)
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.

Wieso wird "während das Plugin in Free noch freigegeben wird", "das nächste von der Anwendung über BASSVIS_ExecutePlugin" geladen? Genau da ist ja das Problem, d.h. Du musst eben in ExecutePlugin warten, bis Du laden kannst.

Entweder (am einfachsten) verweigert 'BASSVIS_ExecutePlugin' das Laden, solange ein Plugin im Speicher ist, dann muss der Aufrufer selbst dafür sorgen, das das so lange probiert wird, bis die Routine ein 'Ok' liefert.

Oder 'BASSVIS_ExecutePlugin' wartet selbst, bis kein Plugin mehr im Speicher ist.

Und das 'kein Plugin mehr im Speicher' erledigt deine Lade/Entladelogik über ein einfaches Flag.


PS: 'Timing' ist bei Multithreading immer gleichbedeutend mit Synchronisationsobjekten und nie mit 'Sleep'

EWeiss 26. Dez 2013 21:40

AW: FastSwitch
 
Zitat:

PS: 'Timing' ist bei Multithreading immer gleichbedeutend mit Synchronisationsobjekten und nie mit 'Sleep'
Ja! In meiner Verzweiflung habe ich alles versucht ;)
Man möge mir vergeben.. hehehehe


Zitat:

"das nächste von der Anwendung über BASSVIS_ExecutePlugin" geladen?
Das ist ja die frage?

Normalerweise geht man so vor das wenn man eine Taste drückt diese auch wieder loslässt.
Oder aber man geht hin und löst den Schaltvorgang erst dann aus wenn die Taste released (losgelassen) wurde.
In dem fall gäbe es dann auch überhaupt keine Probleme da bis dahin jedes Plugin entladen wäre.

Jetzt habe ich in diese Anwendung ein KeyUp Event eingebaut um genau das Problem auf dieser weise zu regeln.
Allerdings wurde dann rumgemault.

Ein Plugin mit OpenGL/Shadern und was nicht noch alles benötigt mindestens 2 Sekunden bis es entladen und seine resourcen freigegeben hat.
Wenn ich aber in dieser zeit Theoretisch 1000 neue innerhalb einer Sekunde lade kann irgendwas nicht funktionieren.
Jetzt sind die der Meinung das eine Anwendung im Stresstest das aushalten muss.

Nur wie will man da händeln?
Wenn also das neue läd während das alte noch nicht entladen ist und ich setze just in dem Moment VisInfo auf NIL
dann wirkt sich das nicht nur auf das alte sondern gleichzeitig auf das neue aus.

Damit habe ich zu kämpfen.

gruss

Furtbichler 26. Dez 2013 22:33

AW: FastSwitch
 
Mache es doch einfach so, das nicht 1000 gleichzeitig geladen werden, sondern maximal 5. Oder 3 oder 10.

Wenn nur das Entladen so lange dauert, ist das doch wurscht.

EWeiss 26. Dez 2013 23:02

AW: FastSwitch
 
Zitat:

Zitat von Furtbichler (Beitrag 1241124)
Mache es doch einfach so, das nicht 1000 gleichzeitig geladen werden, sondern maximal 5. Oder 3 oder 10.

Wenn nur das Entladen so lange dauert, ist das doch wurscht.

Ich denke du hast mir schon sehr geholfen..
Ich muss mal meinen ganzen repeat Mist rauswerfen und anstelle dessen mit Events arbeiten.


gruss

EWeiss 27. Dez 2013 01:06

AW: FastSwitch
 
Hab jetzt wieder stunden damit verbracht komme auf keinen Nenner. Da kann man nur eins zu sagen :wall:
Ich muss jetzt was pennen.

gruss

EWeiss 27. Dez 2013 17:03

AW: FastSwitch
 
Es scheint mir das die bisherigen Lösungen nicht zum ziel führen.

Delphi-Quellcode:
procedure TBASSSoVis.BassSonVisStop;
var
  WaitRe: Cardinal;
begin
  EndByProgram := True;

  if (RenderThreadId <> 0) then
  begin
    PostThreadMessage(RenderThreadId, WM_QUIT, 0, 0);
    hEventFree := CreateEvent(nil, True, False, nil);
    try
      repeat
        WaitRe := WaitForSingleObject(hEventFree, 15);
        if WaitRe <> WAIT_OBJECT_0 then
          WinProcessMessages;
      until WaitRe = WAIT_OBJECT_0;
    finally
      RenderThreadId := 0;
      BassSoVisFree := True;
    end;

  end else
  BassSoVisFree := True;

end;
WaitForSingleObject blockiert den Thread das ist aber nicht das was ich will
Rufe ich diese mit einer Wartezeit von 2000 auf dann blockiert/wartet der Thread bis diese zeit um ist.
wurde in dieser zeit das Event gefeuert (was aufgrund des Blockierten Threads nicht geht) wird mein Flag auf true gesetzt.
Das trifft aber niemals ein wenn das Event aus dem Thread abgefeuert wird. Also muss ein repeat her
und dann habe ich genau das was ich vorher auch hatte.

Dann kann ich genauso wie bisher Sleep(15) verwenden bleibt sich dann gleich.
Mit nur einem Thread ist das sinnlos es sei denn das Event wird wie in deinem Beispiel external also von außerhalb abgefeuert.

Und dort feuere ich ja quasi ein Event über BassVis_Free; (auch wenn es eine procedure ist)

gruss

Sir Rufo 27. Dez 2013 17:21

AW: FastSwitch
 
Liste der Anhänge anzeigen (Anzahl: 1)
Die grundsätzliche Idee dabei ist folgende:
  • Eine abstrakte Klasse
    Delphi-Quellcode:
    TPlugin
    (alle Methoden sind abstrakt)
  • Ein
    Delphi-Quellcode:
    TPluginGateway
    , dass von
    Delphi-Quellcode:
    TPlugin
    abgleitet ist und die Methodenaufrufe an das echte Plugin weitergibt, wenn es denn existiert
  • Ein
    Delphi-Quellcode:
    TPluginController
    (Thread) der für das
    Delphi-Quellcode:
    TPluginGateway
    das Laden/Entladen des Plugins steuert
  • Ein
    Delphi-Quellcode:
    TPluginLoader
    (Thread) der vom
    Delphi-Quellcode:
    TPluginController
    gestartet wird und entweder eine Plugin-Instanz erzeugt/lädt oder eine Plugin-Instanz zerstört/entlädt

Einzig der
Delphi-Quellcode:
TPluginController
benötigt ein Event und wartet einfach, bis was passiert ...
Delphi-Quellcode:
  procedure TPluginController.Execute;
    begin
      inherited;
      while not Terminated do
        begin
          // Warten bis etwas passiert
          FEvent.WaitFor;

          case State of
            csEmpty : // wenn leer, dann laden
              DoLoading;
            csLoading : // einfach mal nix
              ;
            csUnloading : // einfach mal nix
              ;
            csReady : // wenn bereit, dann entladen
              DoUnloading;
          end;
        end;
    end;
Im Anhang ein komplettes Projekt mit Source und Exe.

Ich verwende allerdings die Klassen der RTL und nicht native API Aufrufe (das sind im Grunde genommen nur Wrapper für die API Aufrufe).

EDIT Anpassungen für D2010

EWeiss 27. Dez 2013 17:25

AW: FastSwitch
 
Danke für deine Mühe werde mir das mal anschauen. ;)
Zitat:

Ich verwende allerdings die Klassen der RTL und nicht native API Aufrufe
Das ist kein Problem ob ich TThread oder API nehme kommt sich gleich.. mehr oder weniger ;)

Hmmm sehe schon!
Du verwendest XE ?

Zitat:

[DCC Fehler] PluginController.pas(30): E2137 Methode 'TerminatedSet' nicht in Basisklasse gefunden
[DCC Fehler] PluginController.pas(122): E2250 Es gibt keine überladene Version von 'WaitFor', die man mit diesen Argumenten aufrufen kann
[DCC Fataler Fehler] dp_178190.dpr(10): F1026 Datei nicht gefunden: 'Vcl.Forms.dcu'
Auch nach Änderung auf
Zitat:

uses
Forms,
geht es nicht kommen dann die anderen oben angezeigten Fehler

gruss

Sir Rufo 27. Dez 2013 17:50

AW: FastSwitch
 
Ich habe das angepasst und erneut hochgeladen (siehe letzter Beitrag)

EWeiss 27. Dez 2013 17:58

AW: FastSwitch
 
Zitat:

Zitat von Sir Rufo (Beitrag 1241205)
Ich habe das angepasst und erneut hochgeladen (siehe letzter Beitrag)

Danke ;)
Hatte es auch schon so weit allerdings macht es immer noch ärger.

[DCC Warnung] PluginGateway.pas(29): W1010 Methode 'Create' verbirgt virtuelle Methode vom Basistyp 'TPlugin'
>> constructor Create; reintroduce;

stürzt ab..
FEvent := TEvent.Create( nil, False, False, '' );

Delphi-Quellcode:
  constructor TPluginController.Create;
    begin
      inherited;
[DCC Fehler] PluginController.pas(56): E2008 Inkompatible Typen
>> inherited;

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:49 Uhr.
Seite 4 von 5   « Erste     234 5      

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