OberonCore
https://forum.oberoncore.ru/

Окончательное решение по не-блокировке Action и GUI?
https://forum.oberoncore.ru/viewtopic.php?f=24&t=5906
Страница 1 из 1

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 21:31 ]
Заголовок сообщения:  Окончательное решение по не-блокировке Action и GUI?

Приветствую всех.

Жизнь тут заставила решить полностью проблему того, что в некоторых режимах в ББ блокируются Action-ы и не перерисовываются динамические вьюшки.
Пришлось это решить для задачи, где, во-первых, всегда должна выполняться фоновая логика, во-вторых, недопустимо прерывание интерактивной визуализации.
Просьба проверить, указать на потенциальные косяки. И при желании внедрить в сборки и т.п.

История вопроса:
- в некоторых режимах взаимодействия с пользователем перестают выполняться фоновые Services.Action И\ИЛИ перерисовываться динамические вьюшки (увидеть легко на примере "кубик не крутится, часики не тикают" - для Obx->New Cube и Tools->Insert Clocks).

Обсуждения по этой теме:
viewtopic.php?f=114&t=4287&p=79196&hilit=Ports+Input#p79196
viewtopic.php?f=31&t=367
viewtopic.php?f=24&t=370

Суммирую здесь.
В исходном ББ от Оминк (и в том числе в сборке OberonCore) это происходит в следующих случаях:
1) При выпаденном меню или контекстном меню.
Это исправлялось когда-то после обсуждений на форуме Александром Ильиным в одном из его патчей (http://ajsoft.narod.ru/blackbox/index.htm, http://blackboxcb.livejournal.com/)
Я так понимаю, что в некоторых сборках коллег, в частности, у Ивана Денисова в 1.7, этот патч есть.
Там идёт добавление в процедуру HostWindows.Idle операций Services.actionHook.Step и Windows.dir.Update(NIL) - для перерисовки всех окон. Процедура Idle дёргается операционкой, пока какая-то из функций WinApi работы с меню блокирует выполнение.

2) Если вьюшка хочет последить за мышкой при зажатой клавише, то ББ предлагает блокирующий способ, который и критиковали, и защищали (см. ссылки на обсуждения выше). В HandleCtrlMsg при TrackMsg мы можем сделать цикл и следить за мышью через f.Input.
Разумеется, при этом управление остаётся в этом цикле, пока пользователь не отпустит кнопку мыши.
Исправление вносил Marco Ciot, потом Александр Ильин вводил в своём общем патче "PaintProblem".
Решение, естественно, требует добавления в процедуру HostPorts.Rider.Input вызова Service.actionHook.Step. Вызывать перерисовку экрана оттуда, конечно, нельзя (это высокочастотный цикл опроса мыши).
Решение:
Код:
   PROCEDURE (rd: Rider) Input* (OUT x, y: INTEGER; OUT modifiers: SET; OUT isDown: BOOLEAN);
      VAR msg: WinApi.MSG; wnd, mw: WinApi.HANDLE; pt: WinApi.POINT; res: INTEGER; set: SET;
   BEGIN
      Services.actionHook.Step;   (* marco ciot:060325 *)
      (* WinApi.Sleep(1); *) (* ИЕ - Не нужно, раз мы даём работать задачам *)

Предыдущие авторы не убирали Sleep(1). Я считаю, что теперь стоит его убрать. Не вносить дополнительных тормозов. Лучше подгрузить процессор на период удержания мыши пользователем, чем внести лишние паузы.

На этом история имеющихся решений заканчивается.
Но не заканчиваются проблемы.

3) Остаются блокировки при удержании мыши зажатой над стандартными контролами (button, только тестьте над активным, с командой, над disabled эффекта нет; в момент протяжки выделения в TextEdit, в момент задержки клика на кнопке SpinEdit).
Блокирующий цикл находится в HostCFrames в процедуре HandleMouse (там второй REPEAT).
Решается всё тем же добавлением туда Services.actionHook.Step.

4) После всего вышеописанного Services.Action не прерываются никогда. Однако "кубик не крутится, часики не тикают" в случаях 2) и 3) (в случае с меню нормально, так как там обновляем все окна).

О решении этой проблемы - в следующем сообщении.

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 22:05 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Как реализуется динамическая графика в ББ, можно посмотреть на примере того же ObxCubes и StdClocks.
В модуле заводится Action, который при каждом своем исполнении шлет широковещательное своё сообщение через Views.Omnicast. Omnicast доставляет его вообще всем-всем вьюшкам, которые в данный момент видны на экране.
(Т.е. всего в документе открытом может быть хоть миллион вьюшек - реально сообщения пойдут десятку тех, которые видны).

Наша вьюшка реагирует на это сообщение своего модуля и объявляет себя на перерисовку (Views.Update(self, ..)).
Ну, плюс, она взводит флажок в record-е сообщения, чтобы рассылающий Action знал, есть на экране хоть одна на него реагирующая вьюшка (и тогда выполнялся без промедления) или нет (и тогда можно поспать секунды-пол или сколько там).

После вышеназваннных правок Action-ы работают - т.е. вьюшки сообщения получают.
Но они вызывают для себя отложенное обновление. А это обновление выполняется в главном цикле приложения.
А пока мы сидим в каком-нибудь цикле блокирующем (Input и т.п.), до этого обновления дело не доходит.

Можно ли обновляться не отложенно, а принудительно?
Да. Так делает, допустим, StdLog. Если вы печатаете из любого цикла, то он обновляется.
Если мы в него залезем, то увидим, что вызывается Views.RestoreDomain - это инициирует принудительную перерисовку всех вьюшек, видимых на экране, имеющих указанный Store.Domain (т.е. относящихся к одному документу).
Рядом во Views мы видим Views.RestoreRoot, которая требует корневого фрейма (корневой фрейм - фрейм окна) - и тоже инициирует принудительную перерисовку.

Очевидно, что это примерно одинаково "глобально" - в том плане, что применяется к целому окну.
Т.е. позволять вьюхе самой дёргать это нельзя. Если их там в этом окне 100, то каждая дернет...
Т.е. Action должен накапливать эти корневые домены ли, фреймы ли, не включая их повторно - и потом для них всё вызывать.

Другой вариант: всё же обновляемся не принудительно, а через Views.Update, просто Action после широковещания инициирует фазу общей отложенной перерисовки.
Windows.dir.Update. Я так понимаю, что тупо Windows.dir.Update не стали ставить в эти жадные циклы потому, что нужно было бы городить какую-то временную синхронизацию, чтобы вызывать не каждый раз, а пореже. Никаких принципиальных проблем типа "нельзя вызывать, находясь внутри обработчика сообщения" там не должно быть, т.к. Windows.dir.Update тупо вызывает Views.ValidateRoot для root-фрейма, ну а мы вызываем RestoreRoot, что отличается только оптимальностью (Validate перерисовывает измененённые прямоугольники, Restore - всё). В любом случае, это я не пробовал, попробую, когда допишу этот пост.

В итоге, целесообразно завести отдельный модуль (KrlDynRestore), в котором будет один такой Action, Omnicast-ящий сообщение регулярно, все вьюшки, хотящие быть динамическими, его ловят - и требуют своей перерисовки, вызывая процедуру из KrlDynRestore. А в ней уже можно экпериментировать с разными методами.
В вьюшках ББ используется ModelMsg. Оно передаётся каждой вьюшке по одному разу. Для Views.RestoreDomain это подошло бы, для RestoreRoot - уже нужно знать все кадры, в которых отображается вьюшка.
Поэтому используем ViewMsg. Он будет передан каждой видимой вьюшке один или несколько раз, с каждым кадром, в котором она видна. Что нам и требуется.

Код:
PROCEDURE (v: View) HandleViewMsg (f: Views.Frame; VAR msg: Views.Message);
BEGIN
  WITH msg: KrlDynRestore.Msg DO
    msg.consume := TRUE;
    IF ... если нам пора перерисовываться, по нашей там частоте и проч. ... THEN
      KrlDynRestore.Update(v, f)
    END
  ELSE
  END
END HandleViewMsg;

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 22:22 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

В итоге, хотя сначала я делал через принудительную перерисовку,
работает решение, когда KrlDynRestore.Update вызывает Views.Update для данной вьюхи (это, технически, помечает её прямоугольники в окнах как требующие обновления) и добавляет корневой фрейм окна в список.
Затем Action после Omnicast-а для всех добавленных в список корневых фреймов вызывает Views.ValidateRoot.
Это получается оптимальнее, чем дёргать Windows.dir.Update(NIL), т.к. применяется только к тем окнам, в которых есть изменившиеся вьюшки.

И, кажется, исходное моё решение с вызовом RestoreRoot - опасное. У RestoreRoot есть предусловие, что у обновляемого фрейма нет накопленных отложенных изменений... А "кто их, зверюшек, знает", что там по широковещанию вьюшки накопят... (RestoreDomain гораздо хитрее устроена - и она как раз документирована для использования, в отличие от RestoreRoot).

В итоговом решении используется документированное или известное, как Windows.dir.Update(NIL): Views.Update документирован, а ValidateRoot является просто оптимизацией для Windows.dir.Update (который, собственно, тупо и вызывает ValidateRoot для всех окон).

Ниже приведу исходник KrlDynRestore. Там ещё у Update добавлен параметр period: вьюшка может указать в милисекундах периодичность обновления, и чаще неё её не будут перерисовывать. Только если используется period, то нельзя мухлевать в самой вьюшке, надо честно вызывать Update при каждом Omnicast-сообщении (как мухлюют часы, допустим, сравнивая, изменилась ли секунда).

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 22:25 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Код:
MODULE KrlDynRestore;
   IMPORT Views, Services, Robust := KrlRobust, Dates;

   TYPE
      Msg* = RECORD (Views.Message)
         tick-: LONGINT;
         consume*: BOOLEAN
      END;

      Action = POINTER TO RECORD (Services.Action) END;

   VAR
      resolution-: INTEGER;
      refreshInterval*, idleInterval*: INTEGER;

      ac: Action;

      lastT, curT: LONGINT;

      in: BOOLEAN;

      roots: ARRAY 128 OF Views.RootFrame;
      rootsN: INTEGER;

   PROCEDURE ActionTry (VAR msg, par2: ANYREC; IN par3: ANYREC);
   BEGIN
      Views.Omnicast(msg)
   END ActionTry;

   PROCEDURE RestoreRoots;
      VAR i: INTEGER;
         f: Views.RootFrame;
   BEGIN
      FOR i := 0 TO rootsN-1 DO
         f := roots[i];
         Views.ValidateRoot(f);
         roots[i] := NIL
      END;
      rootsN := 0
   END RestoreRoots;

   PROCEDURE (a: Action) Do;
      VAR try: Robust.Trial;
         msg: Msg;
   BEGIN
      try.proc := ActionTry;
      msg.tick := Services.Ticks();
      msg.consume := FALSE;
      curT := msg.tick;
      in := TRUE;
      try.Try(msg, Robust.noRec, Robust.noRec);
      in := FALSE;
      lastT := msg.tick;
      RestoreRoots;
      IF msg.consume THEN
         Services.DoLater(a, refreshInterval)
      ELSE
         Services.DoLater(a, idleInterval)
      END
   END Do;

   PROCEDURE Update* (v: Views.View; f: Views.Frame; keepFrames: BOOLEAN; period: INTEGER);
      VAR i: INTEGER;
         root: Views.RootFrame;
   BEGIN
      ASSERT(in, 20);
      Views.Update(v, keepFrames);
      IF (period = 0) OR (lastT < curT DIV period * period) THEN
         IF rootsN = LEN(roots) THEN
            RestoreRoots
         END;
         root := Views.RootOf(f);
         i := 0;
         WHILE (i < rootsN) & (roots[i] # root) DO
            INC(i)
         END;
         roots[i] := root;
         IF i = rootsN THEN
            INC(rootsN)
         END
      END
   END Update;

BEGIN
   resolution := 1000;
   refreshInterval := Services.now;
   idleInterval := 500;
   NEW(ac);
   Services.DoLater(ac,Services.now)
CLOSE
   Services.RemoveAction(ac)
END KrlDynRestore.

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 22:34 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Пример переделанных часиков под это.

Код:
MODULE Krl_devDynRestore;
   (* Modified from StdClocks *)
   IMPORT
      Dates, Math, Domains := Stores, Ports, Stores, Models, Views, Properties,
      TextModels, KrlDynRestore;

   CONST
      minSize = 25 * Ports.point; niceSize = 42 * Ports.point;
      minVersion = 0; maxVersion = 0;

   TYPE
      StdView = POINTER TO RECORD (Views.View)
         time: Dates.Time
      END;

   PROCEDURE Cos (r, g: INTEGER): INTEGER;
   BEGIN
      RETURN SHORT(ENTIER(r * Math.Cos(2 * Math.Pi() * g / 60) + 0.5))
   END Cos;

   PROCEDURE Sin (r, g: INTEGER): INTEGER;
   BEGIN
      RETURN SHORT(ENTIER(r * Math.Sin(2 * Math.Pi() * g / 60) + 0.5))
   END Sin;

   (* View *)

   PROCEDURE DrawTick (f: Views.Frame; m, d0, d1, s, g: INTEGER; c: Ports.Color);
   BEGIN
      f.DrawLine(m + Sin(d0, g), m - Cos(d0, g), m + Sin(d1, g), m - Cos(d1, g), s, c)
   END DrawTick;


   PROCEDURE (v: StdView) Externalize (VAR wr: Stores.Writer);
   BEGIN
      v.Externalize^(wr);
      wr.WriteVersion(maxVersion);
      wr.WriteByte(9)
   END Externalize;

   PROCEDURE (v: StdView) Internalize (VAR rd: Stores.Reader);
      VAR thisVersion: INTEGER; format: BYTE;
   BEGIN
      v.Internalize^(rd);
      IF ~rd.cancelled THEN
         rd.ReadVersion(minVersion, maxVersion, thisVersion);
         IF ~rd.cancelled THEN
            rd.ReadByte(format);
            v.time.second := -1
         END
      END
   END Internalize;

   PROCEDURE (v: StdView) CopyFromSimpleView (source: Views.View);
   BEGIN
      WITH source: StdView DO
         v.time.second := -1
      END
   END CopyFromSimpleView;

   PROCEDURE (v: StdView) Restore (f: Views.Frame; l, t, r, b: INTEGER);
      VAR c: Models.Context; a: TextModels.Attributes; color: Ports.Color;
         time: Dates.Time;
         i, m, d, u, hs, hd1, ms, md1, ss, sd0, sd1,  w, h: INTEGER;
   BEGIN
      IF v.time.second = -1 THEN Dates.GetTime(v.time) END;
      c := v.context; c.GetSize(w, h);
      WITH c: TextModels.Context DO a := c.Attr(); color := a.color
      ELSE color := Ports.defaultColor
      END;
      u := f.unit;
      d := h DIV u * u;
      IF ~ODD(d DIV u) THEN DEC(d, u) END;
      m := (h - u) DIV 2;
      IF d >= niceSize - 2 * Ports.point THEN
         hs := 3 * u; ms := 3 * u; ss := u;
         hd1 := m * 4 DIV 6; md1 := m * 5 DIV 6; sd0 := -(m DIV 6); sd1 := m - 4 * u;
         i := 0; WHILE i < 12 DO DrawTick(f, m, m * 11 DIV 12, m, u, i  * 5, color); INC(i) END
      ELSE
         hd1 := m * 2 DIV 4; hs := u; ms := u; ss := u;
         md1 := m * 3 DIV 4; sd0 := 0; sd1 := 3 * u
      END;
      time := v.time;
      f.DrawOval(0, 0, d, d, u, color);
      DrawTick(f, m, 0, m * 4 DIV 6, hs, time.hour MOD 12 * 5 + time.minute DIV 12, color);
      DrawTick(f, m, 0, md1, ms, time.minute, color);
      DrawTick(f, m, sd0, sd1, ss, time.second, color)
   END Restore;

   PROCEDURE (v: StdView) HandleViewMsg (f: Views.Frame; VAR msg: Views.Message);
      VAR w, h: INTEGER;
         time: Dates.Time;
   BEGIN
      WITH msg: KrlDynRestore.Msg DO
         Dates.GetTime(time);
         IF v.time.second # time.second THEN   (* execute only once per view *)
            msg.consume := TRUE;
            v.time := time;
            KrlDynRestore.Update(v, f, Views.keepFrames, 0)
         END
      ELSE
      END
   END HandleViewMsg;

   PROCEDURE SizePref (v: StdView; VAR p: Properties.SizePref);
   BEGIN
      IF (p.w > Views.undefined) & (p.h > Views.undefined) THEN
         Properties.ProportionalConstraint(1, 1, p.fixedW, p.fixedH, p.w, p.h);
         IF p.w < minSize THEN p.w := minSize; p.h := minSize END
      ELSE
         p.w := niceSize; p.h := niceSize
      END
   END SizePref;

   PROCEDURE (v: StdView) HandlePropMsg (VAR msg: Properties.Message);
   BEGIN
      WITH msg: Properties.Preference DO
         WITH msg: Properties.SizePref DO
            SizePref(v, msg)
         ELSE
         END
      ELSE
      END
   END HandlePropMsg;


   (** allocation **)

   PROCEDURE New* (): Views.View;
      VAR v: StdView;
   BEGIN
      NEW(v); v.time.second := -1; RETURN v
   END New;

   PROCEDURE Deposit*;
   BEGIN
      Views.Deposit(New())
   END Deposit;

END Krl_devDynRestore.

"Krl_devDynRestore.Deposit; StdCmds.Open"


Ниже в StdCoded привожу KrlDynRestore и модуль KrlRobust, используемый в KrlDynRestore.

Код:
StdCoder.Decode ..,, ..Ha....3Qw7uP5PRPPNR9Rbf9b8R79FTvMf1GomCrlAy2xhX,Cb2x
 hXhC6FU1xhiZiVBhihgmRiioedhgrZcZRiXFfaqmSrtuGfa4700zdGrr8rmCLLCJuyKtYcZRiX
 7.2.s,64H.0k,5TWyql.bnayKmKKqGomC5XzET1.PuP.MHT9N9ntumaU2,CJuyKtQC98P9PP7O
 NbXmb.2.og6k2EjW.,6.cUGpmWLuOpoKqvCbHZiYpedhA704TeKKw.bHfEWUmL.6..D.F606.C
 cIhgsNHT9N9ntQ8qorG4704D.CbB,708T1U.E7O.T.Jc,2.,U,Qa,U00.bnUGLu8ro8quGrmCL
 WKqtE0E.klE.0.p.0.4E.6.JFA0z.U.2m,.5.mzzzzzB.6xzzzz5czzzzz5cszzzzL,UgzzzzT
 1.Gyzzzzh5AU0KyBU.2.e22.e,2.AU.Ue.E.mP,U62.0kzk.O.g8A.E54.16,6.HQ.IU0KyBU.
 2..c4E.k.0.e0M.6YE.C.8ExzzzzT,4.,c.ZzzzzzS.0k0lzXGJ0mCGs8GMECF0vF09G0vF09F
 0vF01GBGMEmF0rF0vF0DF0vVTYkSYkWUbYkRYkSM67g67A47A9,tA7wC7gD7QA7AA7wC7AH7QD
 7gD7QB7A6Z7Vj7VV7Vl7Vt7Vx7Vd7Vf7Vn7V18V38VZ7Vl7Vf7V,d8HN1PuH7OJNOF,tGZ9PZu
 P3PRb9RrN1PM0HOHVuHZ8J,tG9fQRPNN99,tI,dCv76bOKb8J9OHrN1PM0dOKVOFPM0H6JZPSV
 eQTvMJ76v76VeITuE98FfeI986FdJ1eI,7Q1fQX79,7Q1fQZdC,NEROKZOF5uC,NGR86VPMCHR
 0mUu2AZvgV7AVIldaqn0mS0Gc.UkBgmB4Grw0rMmGE05Z79,7RnHNmGE0rkQag2YoBDbdC,NGR
 8J9uF9eIHtCPM1a.HPMNf8,ND,dI9uETeI7O1HM0H6QZvP5HR0Ge8rw03in4ak2akriqKeHE8o
 byIaKoUuoRqk2aUZJimxhmhZg2YkRghIbUAdC,qk2akWuIWin4cJ1eIPM0uqr8pmCKJeHE8pWC
 20mWuIWi1aEu8rw03eHEGJtQ8in4aUkBgmJbUAcGJe,BfUQaUwd43YGh6M16QYZUYCeHEaIb.M
 F.MMVvETPRR9Rp76H0sCPM1H6IZuH506FT96F7SN76n99,dSp76HeHUdk28oWSoYuo4ak2Gbt,
 F7Q1fQr8Ave9VPMZ990bm,dPSV99,7Q1Xlgfi2iV,.dPS.8niuGs44.YitN8PM09eH0GWyqRqk
 4a..2ZKVoJbUYemBhVN8,7JZPSJ76FdJ1WklM6Q1HNe1R0i1UnI510AZg2YChcLRbBAV0,UV,2
 YugbUQdZJCoZoJiV3CkRqk2aEuAD66pVHpZKBcA3ZIJitR8mGEGLL0LtyqlamRM0VXP3405,dC
 v76Ac2Jec2iVJilAZv2YkBgmR9YC0GRq1Gpg0JI0rkA4qk2.XVk,kU.8nIiHE05r0d1UI,I4q.
 EN6Q.A6UnAZv2YklhEu.6J.bVBkZKKtu4GJtaLIGormGE0HK0GMm0HtCPM0GLLyqp0GRqX9,YC
 .0mS0Gu8rk05sCEt44EEe1..kR0GIeGEGH0jH0zI01GNGsOGMUGsWGsSGMQGsWGMEGJtaLEemI
 qk2akYOIEuLuumriaI3d3pdBA,H6RRNNZfQTHEenS.MNZnRqk2A,0rl0GRq1.VvMrN1HM098Hb
 OFPM0HM0gAy46ArN1Hk26Q00gV7AV3p7PM09eH0Ge8bvgVBgcCZ6LeQN1c93QwdONQcjphotPN
 9P9fQbf9b8R7vEdfQN9F9vQ59.X5..RtETfPd16F9vQ59.C2dPMgA.Z1...bf9.EWE.8D2.Y02
 .A,,E.0..4E,5TeK4ZORNPNZvQRtIIepZBG20ksH3.bf9ZORNPNG20EtD.2.i8S.C80E.QE.sQ
 RtIQeoBjghg2hgn7.X5.u0n9PU.Iy5.,.60cK2.,U00.umUG5.70,E0E...7,,M.,.,.,tcp00
 ESuz.oeh7.16.A.2U.E,9z4U...p.0.4.I3E.6.VQ.E..YVsH4EKithQVs9E3Qw70ktQcj,.E6
 E...F.,.aU.EAjot2YbQI,AzJE.nT32XD3B,h8l2Hf....
 --- end of encoding ---


Код:
StdCoder.Decode ..,, ..Ah....3Qw7uP5PRPPNR9Rbf9b8R79FTvMf1GomCrlAy2xhX,Cb2x
 hXhC6FU1xhiZiVBhihgmRiioedhgrZcZRiXFfaqmSrtuGfa4700zdGrr8rmCLLCJuyKtYcZRiX
 7.2.s,MoJ.0k,5TWyql.bnayKmKKqGomC5XzET1.PuP.MHT9N9ntumaU2,CJuyKtQC98P9PP7O
 NbXmb.2.wX8k2k9e.,E.cUGpmWLuOpoKqvCbHZiYpedhA704TeKKw.bHfEWUmL.6..D.1S06.,
 sUGpmWbBxhYhAbndMHT9NY6Mw.sQq2Y6cwB.0.Ly,w,Qs5E.0E.kNV00.bnUGLu8ro8quGrmCL
 WKqtE0E.kHU.EBU.U,.JFA0z.U.2m,.d01cUZT1E..UO.,.16.c8.2UwK.6,6.B21s0k4k.0,,
 6.3.1M16.nu.AU52.Am0kzrobGoemoW0mZ8LqGowuKdKqtGrr8bvgV7AdB3eDJeI3YKBhZtQN7
 6bONZfRHvM9vQN76ZuP3PRb9R,dCv76LeQ8pr84mGEGokGrmCrRqk4aEeaJcKo4ak2qotSKJ0m
 S0GdKoVyIdGIEWGfaqmc9PONbvQ1vN9P8PM0HM0dPO5vOPdC,7HTeHDOGR8JrN1HM0HsMTfPbP
 RPHJeHE8obyIaKoUuo4ak2KIbGoRqk4ak24olGroyKr0mS0GcyoYuIeKId0GeyIE8pWC2sI9fQ
 UiAcXZidlI0mWuIWi1OpU8p4ak28rmCrrmquGroyKrqGR0mYuIeKoXKIdin4ak28baJiZRicBd
 iZiZJiqBggJZg2YdZgghg7phohAER0mYu2UBAV7AgXJbUAcXZidlRqk46P1vQd9JN765PRZ9Jp
 76NuHUvM1AhiJbUI6Uvg,IijxhoRiu22ZeI1OK,NAZ7C,tHB86hOO91ZuPT9RBeQ1PP9vCPM0H
 .CLbeHEa2.2eGxd1hc2heGhcUAcXZCYemBjU2ZKBcG3YhRibZZU2iVJimIbUAcCBfGhc1RbUAd
 C3YkBgmRau2Y,p7M8rN1HcE9uFHeHPM0OpoK4yoquqoCqkCLuWmqCrnam4akWuYUAcXZCUvgVB
 A,.cI9vQd1ZuPT9Rin4ak2OpU2YdJbUA7.aU7ogu2YKBBcIcF..cFTeI,NO,dCv76V76duH,dQ
 TvPCLbqmM0GWyo4ak266pND,dQTvPQfdhfvgV7A,hOOEf4KqaKm4KuKKdyqr2ZaBZvgV7EtktE
 EenSod7ZdBAV7g6iX7cQEb0GRqXkgV7gcC76ZONb1.rl4..FNMp761uMkIYcjRbBA,hOEYimBj
 u2YGxhWViYemBhVZhvgV7M0PvQDfC,NHbvNrN1HcE.GLtaLL0Ltyql0GRqHE4olUIlRA,PXiYi
 dRgf3Yug5bONZXXVIBhXRhn3ZdQbBA,klyKrC5996pNDOoUmodKoRq.5PRZ9J,dCvlqCrnuGuQ
 ArN1HM0HHEe1deIfOFrN1HEuEe8rwWmqCrnmWGxhW,RvPZON599,dI.UdQbBko.B0Ug,,dCvlq
 c9.IeZRio,.HkYOIEqqtsM.GJYKIbqk2AVHhgmpCEWyKa4KuKKtWmkmGE8rmOKt6Ou4kIqk2ak
 WmodKo4ak2a.sM..AhY,.kWuYBAV3FEGoriXBUD,MJV9N19R9f8,78hfC,,kosC,dNp76h0bHX
 8rkq4,tO9PNVfFZPMQiu2Y0x7UU2iZJidxhYJbUAdC,amRq.h0H1.r,HcQcC,dJH183O2QbBcE
 .4odCpW8JeWmouKK0GN0nIin4AVKBBMJV9N1Xcoig2YfhgZ,QidQbBkY68VPNZ1,ND,7AH76Te
 I,78NPMb9RYbUQgpV2BdK3Ykhgm,J76VPNkI0GeW2M0HWmxhjtQRmS0GaKIbWGtyqrM8,7JF0M
 0Z0.gV7AV7g6i1IC2YuEfaqmEdkbOKIOqIi1AhUIbx6ArN1HUL3d7Zd33YcAhUYbUIijxBbfHH
 76B76FdQTvPQ9QYUIijxBH767uHk2aIbCIIaqIqk2AV3,cQsQERcQsCP.HeFaKEqHE8rrsQR86
 d8G90AV7p78rry4am4ak2g6qU7.K2,NJV9NsCPM13OFD08rmC5f9R66pND4HM0HMi1ZPNB1oB9
 10GRqXH,51RvPjvCPM0H9NNPN..f7AVtCPEbKofWmkCqIi1bON.G21XmllmmdKKt.u4HN158HT
 uI9O1HsI91EdKqqyKvKqUCKuEI4qlam4KIbGY9JigZ6.oZ0CyIhACoruKu8rrmKqKKtCLLCJuQ
 coJigZcZRiX3Ul1.UiQcjpho,YcZRiX3.5011.85...CLL.U2V.IS6.636.M00.,..1cUXDJ9X
 GhighgmRiiQ88pum470,Mwd0UnpZGhighA70,cw5.0.L3D.53,6.C6W5ktumdsIdPSNPN7ONbH
 .4D.o3aLq.,cwD.0.E2Eh2.,6.IE.EL4IuElYCGom6.G.0..676.16.6.665hKE.4vl5UTyB4E
 .M.6.,U0KyB.,..eF.E.k.Ue.E.0t.U..61lbAUgQnPt0lLU8ssH2cPsET1.UE2.0..606.k22
 .WtZCbUwYX8Utj00MyfUMwdc7cJ7a0.6J,...
 --- end of encoding ---

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 22:40 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Мои лично проблемы этим решены, т.к. мои динамические ответственные вьюхи сами опрашивают визуализируемое состояние данные, не используя модели и уведомления от них.

Но, в принципе, возникает вопрос, а почему бы не дорешать проблему и Windows.dir.Update(NIL) периодическим из этих жадных циклов. Вопрос, насколько часто дёргать. Нет ли других подводных камней? Наверное, нет.
Тогда, кстати, и по-старому написанные вьюшки и часики заведутся.

Тем не менее, написанный выше модуль, считаю, написан не зря, потому что теперь рабочий Action и Omnicast собраны однократно, а не под каждый тип вьюшек, избегаем оверхеда - и в коде, и по быстродействию (а Omnicast не так дешев).
Во-вторых, мы имеем точку вызова, к которой обращается любая динамическая вьюшка, и можем в ней чо-нибудь мудрить-пробовать... Т.е. для совсем часто обновляемых вьюшек, видимо, это разумно - отдельная перерисовка такая, от основного цикла. Хотя сейчас фактически один хрен это будет происходить не чаще, чем и общее обновление по главному циклу окна.

Приглашаю коллег дальше додумать ) У меня практический стимул исчерпан пока.

Автор:  Александр Ильин [ Воскресенье, 02 Октябрь, 2016 22:57 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Круто, Илья! Рад видеть, что проблемы решаются. : )

Спасибо за упоминание меня в этой истории.
Жаль, что Marco Ciot в процитированных исходниках написан с ошибкой (Kiot - не правильно, правильно Ciot).

Автор:  Илья Ермаков [ Воскресенье, 02 Октябрь, 2016 23:14 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Поправил выше. Каюсь, сначала вообще опечатался и написал Macro...
Впрочем, программист на такое не обиделся бы, я думаю :)

Автор:  Info21 [ Понедельник, 03 Октябрь, 2016 17:07 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Илья Евгеньевич, может, Вам сделать лекцию-обзор логики Views -- и как туда вписывается the решение?

Лишний раз обдумаете всё при подготовке :)

Автор:  Илья Ермаков [ Вторник, 04 Октябрь, 2016 15:05 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Если имеется в виду унутряная их логика, то беру самоотвод.
Я не знаю насквозь все эти вещи. Знаю кусочно, где приходилось что-то подстругивать ))

У нас тут эксперты есть и по Gtk-порту, и по OpenGL-порту :)

Автор:  prospero78 [ Пятница, 21 Октябрь, 2016 13:23 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Да, часики тикают)) И проц точно грузится на 100%.
А разве нет в WinAPI аналога Idle? И всё-таки вопрос не решён с мультипроцессами. Или я что-то не знаю?

Автор:  Илья Ермаков [ Пятница, 21 Октябрь, 2016 14:54 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

На 100% в какой момент?

Автор:  prospero78 [ Пятница, 21 Октябрь, 2016 18:03 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

При выделении текста и удержании нажатой мышки.

Автор:  Илья Ермаков [ Пятница, 21 Октябрь, 2016 18:21 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Ну да.

"А ну и хрен с ним, с плащом".

Создавать искусственно протормозы для Action-ов не правильно.

Автор:  Trurl [ Суббота, 05 Ноябрь, 2016 21:50 ]
Заголовок сообщения:  Re: Окончательное решение по не-блокировке Action и GUI?

Неправильно искусственно ускорять Action. Эта тема обсуждалась в рассылках. Позиция разработчиков: Action - выполняются в свободное от работы время и это своего рода контракт. Если вам нужна гарантированая периодичность, заводите другой механизм.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/