MQLで書かれたUIのギャラリー - ページ 54

 

フルスクリーンのキャンバスも変更ごとに完全に再描画していますが、50ミリ秒もかかりません。

最もコストがかかるのはテキストの描画だ。そのため、毎回TextOutを使わないように、配列に格納している。その結果、ずっと速くなった。

 

現在の主な課題は、インターフェイスの制御を プログラムで制御できるようにすることだ。

ユーザープログラムとエンジンの共生において、グラフィカル・コアは両者のアルゴリズムからグローバルなレベルで見えるからだ。問題は、ユーザーがカーネルの扱い方を知らないことだ。彼はエレメント管理の原理を知らないし、理解していない。そのため、カーネルにアクセスして値を変更できるような関数、つまり使い慣れたラッパーを与える必要が ある。

しかし微妙なニュアンスがある。関数の名前が長すぎるのだ。結局のところ、インタラクティブ・エレメントの各機能ラッパーは、エレメントとウィンドウの名前を含むべきである。これは名前間の方向づけのために必要である。そうでなければ、ユーザーは混乱しやすく、機能ラッパーを理解できないでしょう。また、名前が一致することがありますが、これは全く良いことではありません。つまり、要素の名前とウィンドウの名前という2つの要素から名前を生成する必要があるのです。そうすれば混乱はなくなりますが、ラッパー名が長くなりすぎてしまいます。特にパラメータを渡す側では。さらに、インテリセンスですぐに見つけられるように、関数に接頭辞をつける必要があります。これにより、ポップアップサンプルの効率的なフィルタリングが可能になる。便利だ。でも長い!

それだけではない。問題は渡されるパラメーターだ。選択肢は、エレメントやウィンドウのget/set-propertiesのプリセットごとにラッパーを書くか、それぞれのラッパーがユーザーコールからパラメーターの全リストを受け取るかのどちらかだ。これはひどく不便だ。そして最も重要なことは、説明が難しいということだ。


解決策はあり、それは簡単です。それは、抽象的なプロパティのグループ です。ユーザーのプログラム側からもエンジン側からも同時に見えるグローバル変数。

どのように機能するか:

1.エレメントやウィンドウのすべてのラッパーは、中央関数をアドレスとし、そのインデックスを渡します。それを使って、呼び出しのターゲットとなるエレメントやウィンドウを決定します。

2.この呼び出しの後、ユーザーは選択された抽象プロパティのセットを必要な値に設定 します

3.中央関数を呼び出し、c.word "Set "を渡す。

4.セントラルは、抽象プロパティの値をそのグローバル変数から、特定の要素またはウィンドウのターゲットプロパティに設定します。

5.要素やウィンドウを更新し、抽象プロパティをゼロにリセットします。

以上だ。

私見ですが、シンプルで効率的なソリューションで、以下のようなことが実現できます:

a) 厳密な一貫性を必要とする関数にパラメータを渡すことなく、あらゆる要素やウィンドウのプロパティに簡単にアクセスできる。(さらに、渡されるパラメータの数にも制限があります。そして、呼び出しは長くなり、読めなくなる)。

c)プログラム内の任意の場所で値を設定/受信する際に、エレメントとウィンドウのプロパティのセットを自由に組み合わせる ことができる。


もしデメリットを発見した人がいたら、はっきり言ってください。リリースの前にこの問題を調整するのは良いことだと思います。

 
Nikolai Semko CCanvas クラス(使用している場合)の Update 関数に静的カウンタを置き、たとえば count%100 == 0 のときにこのカウンタを表示します。

ニコラス、我々は複数のGUIウィンドウについて話していることを考慮する価値がある。前回のリリースでは17個のウィンドウがあり、それぞれに何百もの要素があります。そして各要素は複雑です。それはパーツのセットで構成されている。各詳細は、必要な値で塗りつぶすために適切な場所を通過する必要があるキャンバスのセクションです。

ウィンドウの平均数を10(パプコフは11のウィンドウのインターフェイスを注文したと記憶している)とし、それぞれが要素またはテーブルのセットを持っていると想像すると、インターフェイス全体の完全なレンダリングに時間がかかる理由が明らかになる。インターフェイスには、アイコン、シャドウ、表面グラデーション、さまざまなフレーム......があることを思い出してほしい。となると、インターフェイス全体の完全な描画には少なくとも500ミリ秒はかかることになる。これはどうしようもない。

ウィンドウの数を減らすか、グラフィックをシンプルにすれば、もっと速くなります。

再描画について - 純粋なChartRedraw()呼び出しはほとんどありません。ChartRedrawフラグはあらゆるところで使われています。このフラグがセットされていると、ChartRedraw() 関数は 25ミリ秒後の次のタイマー反復時に 呼び出されます。 つまり、1回だけです。こうすることで、不必要な再描画を避けることができる。まれに、ChartRedraw() を直接呼び出すこともある

 
Andrey Barinov #:

また、フルスクリーンのキャンバスは、変更するたびに完全に再描画されるが、50ミリ秒もかからない...。

最もコストがかかるのはテキストの描画だ。そのため、毎回TextOutを使わないように、配列に格納するようにしている。その方がずっと速くなる。

10~17個のウィンドウの面積の合計はフルスクリーンよりはるかに大きい。そうだね。それに、影、アイコン、フレームを作るのに必要な二次的な追加描画もある。

TextOutについては 、今度調べて書くよ。面白いアイデアだ。

 

テストを実施した:

デモプロジェクト 1.mqh ファイルに入り、すべてのウィンドウを OOI フラグに設定しました。(初期化時に開く)。

全部で15個のウィンドウがあり、大きさも内容も違います。2 つのウィンドウはスクロールバーとテーブル付き(そのため、キャンバスは部分的に隠され、実際には 2-3 倍長い。全長はスライダーとスクロールバーの比率で判断できます)。総描画領域(最小2000*1000ピクセル。しかし、それ以上だと思う。描画されたパーツの総数は1158個(コア印刷後に確認)。全キャンバスの描画時間は、ゼロから1600~1900ミリ秒。

繰り返しになるが、細部の描き込み量に注目してほしい。影、アイコン、グラデーション、フレーム、テキスト。


描画時間はスクリーンショットにある:


 
描画をスピードアップする方法があるかもしれない。窓の台の下の土台を取り除く。これは、エレメントが配置されている前面の後ろにある大きなキャンバスです。これを取り除けば、2倍速くなる。考えてみます。
 
特定のウィンドウが開いているときだけ描画することは可能ですか?一度に何十もの窓を開くことは稀です。その必要はありません。
 
hini #:
特定のウィンドウが開いているときだけ描画することはできますか?同時に何十ものウィンドウを開くことは稀です。その必要はない。

そのようなことが起こるのは、私を信じてください。私が言っているのは、すべてのインターフェイスのウィンドウを一度に 開く最初の描画についてだけです。最初の描画に一番時間がかかる。そしてその後、すべての画像はすでに保存され、必要に応じてメモリーから取り出される。これは問題ではない。 最初の描画の時間を短縮したいだけなのだから。

 
Реter Konow #:
描画をスピードアップする方法があるかもしれない。窓の台の下の土台を取り除く。これは、エレメントが配置されている前面の後ろにある大きなキャンバスです。これを取り除くと2倍速くなる。ちょっと考えてみます。

これが私が言っているキャンバスです:

1.エレメントがある表側:


2.ウィンドウのボタン(十字、ミニマイザー)、アイコン、名前のテキストがある裏側。しかし、ウィンドウ全体は緑色に着色され、時間も費や されています。しかし、ユーザーにはフレームとウィンドウのヘッダーしか見えない。この場所では無駄な描画が行われていることがわかる:


 
裏側の見えない部分を描画しなければ、窓の最初の描画を少なくとも3分の1スピードアップできると思う。まだ確かなことは言えないので、確認する必要が ある フレームと帽子だけを描画させる。残りはスキップする。いずれにせよ、得るものはあるだろう。