0

Windows用に作成しようとしている小さなアプリケーションがあります。一部のデータを処理するように設計されたバックグラウンド スレッドが混在しているという問題が発生しています。このバックグラウンド エンジンは、アプリケーション GUI (A Windows フォーム) を更新し、そこから情報を取得する必要があります。

これが基本的なアプリケーションのメインです。

int main() {
Engine engine;
Gui g;

engine.run(); // creates a new thread for engine logic
g.ShowDialog();

bool running = false;
while(1)
{
    // Update gui with information from the engine
    g.update(engine.GetState());

    // transition to running
    if(g.isRunning() && !running)
    {
        engine.play();
        running = true;
    }
    // transition to stopped
    else if(!g.isRunning() && running)
    {
        engine.stop();
        running = false;
    }
}
}

私の主な問題は、Gui クラスが管理されているという事実から来ています。以下のクラス宣言を参照してください。

public ref class Gui : public System::Windows::Forms::Form

これら 2 つのことを実際に混在させることはできません。最初はエンジンを Gui に放り込みたいと思っていましたが、管理されていないため機能しません。

ここでの問題は ShowDialog() の呼び出しであることに注意してください。これは、ダイアログがモーダルになり、その後コードが実行されないためです。ただし、Show() を使用すると、Gui は単に入力を更新または処理しません。

解決:

エンジンが Gui 内に含まれているが、別のスレッドで実行されるように、Gui クラスにバックグラウンド ワーカーを作成しました。

    void InitializeBackgoundWorker()
    {
        this->backgroundWorker1 = gcnew System::ComponentModel::BackgroundWorker;
        backgroundWorker1->DoWork += gcnew DoWorkEventHandler( this, &Gui::backgroundWorker1_DoWork );
        backgroundWorker1->RunWorkerAsync( );
    }

    delegate void UpdateCallback(int hp, int maxhp);

    void UpdateGui(int hp, int maxhp)
    {
        this->playerHealthBar->Value = ((float)(hp)/(float)(maxhp) * 100.0f);
    };

    void backgroundWorker1_DoWork( Object^ sender, DoWorkEventArgs^ e )
    {
        aBotEngine engine;
        while(true)
        {
            engine.runnable(NULL);

            array<Object^>^args = gcnew array<Object^>(2);
            args[0] = engine.getPlayerHp();
            args[1] = engine.getPlayerMaxHp();
            this->playerHealthBar->Invoke(gcnew UpdateCallback(this, &Gui::UpdateGui), args);
        }
    };
4

1 に答える 1