SASGIS

Веб-картография и навигация

FlightRadar+SAS

Форум для обсуждения деталей разработки программы SAS.Планета

Модераторы: vdemidov, Tolik

Re: FlightRadar+SAS

Сообщение Smith2007 » 29 июн 2011, 14:53

Так на чем все закончилось?
Результат есть какой?

За это сообщение автора Smith2007 поблагодарил:
IC7K (30 июн 2011, 03:17)
Рейтинг: 5.26%
 
Smith2007
Соображающий
 
Сообщения: 70
Зарегистрирован: 24 май 2009, 14:15
Благодарил (а): 6 раз.
Поблагодарили: 1 раз.

Re: FlightRadar+SAS

Сообщение vasketsov » 29 июн 2011, 18:07

Smith2007 писал(а):Так на чем все закончилось?
Результат есть какой?

А по-моему ещё ничего даже толком и не началось.
Народ застрял на этапе обсуждения протокола.

Код: Выделить всё
SASObjectSet: array of ISASObject

Ребята, вы меня конечно извините, но для таких случаев используются двунаправленные списки, а не массивы.
Добавляется и удаляется объект из них просто по щелчку пальцев.
Для идентификации объекта можно использовать саму ссылку, так как программа и плагин в одном адресном пространстве.
Соответственно никаких счётчиков количества объектов вообще не надо, так как список закольцован. Как повторилась начальная ссылка - так и закончили обход всего списка.

За это сообщение автора vasketsov поблагодарил:
IC7K (30 июн 2011, 03:17)
Рейтинг: 5.26%
 
vasketsov
Специалист
 
Сообщения: 901
Зарегистрирован: 25 июл 2009, 21:15
Благодарил (а): 0 раз.
Поблагодарили: 198 раз.

Re: FlightRadar+SAS

Сообщение IC7K » 30 июн 2011, 03:16

парни, я погряз просто в самом начале
мне не хватает знаний в области программирования

если кто понимает о чем здесь идет речь - помогите решить проблему
я помогу чем смогу
сильный поедает вкусного
IC7K
Новичок
 
Сообщения: 19
Зарегистрирован: 25 фев 2011, 14:35
Благодарил (а): 2 раз.
Поблагодарили: 0 раз.

Re: FlightRadar+SAS

Сообщение vasketsov » 30 июн 2011, 10:37

IC7K писал(а):мне не хватает знаний в области программирования

Здесь программирование ни при чём. Кодинг тут простейший. Тут важно понять весь протокол взаимодействия целиком. А я пока даже не увидел понимания со стороны присутствующих, что инициатором перерисовки точек может быть как хост, так и плагин.

IC7K писал(а):я помогу чем смогу

Предлагаю всё же наоборот. Смею утверждать, что задача несложная даже для непрограммиста.

На всякий случай вкратце объясню, что такое двунаправленный список и как с ним работать.
В двунаправленном списке есть 2 поля, в которых хранятся указатели на предыдущий и последующий объекты соответственно (на примере структуры или объекта - принципиальной разницы нет):
Код: Выделить всё
type
  PStructListItem=^TStructListItem;
  TStructListItem=record
  FPrev: PStructListItem;
  FNext: PStructListItem;
  // прочие поля структуры элемента списка
  end;

  TObjectListItem=class(TObject)
  private
    FPrev: TObjectListItem;
    FNext: TObjectListItem;
    // прочие поля объекта элемента списка
  end;


дальше на примере объекта для итерации делатся вот что:
Код: Выделить всё
  TObjectListHolder=class(TObject,IObjectListHolder)
  private
    FList: TObjectListItem;
    // прочие поля объекта
  private
    // для итерации
    function GetFirst: Pointer;
    function GetLast: Pointer;
    function GetNext(Obj: Pointer): Pointer;
    function GetPrev(Obj: Pointer): Pointer;
  end;

{ TObjectListHolder }

function TObjectListHolder.GetFirst: Pointer;
begin
  Result:=FList;
end;

function TObjectListHolder.GetLast: Pointer;
begin
  Result:=FList.FPrev;
end;

function TObjectListHolder.GetNext(Obj: Pointer): Pointer;
begin
  Result:=TObjectListItem(Obj).FNext;
end;

function TObjectListHolder.GetPrev(Obj: Pointer): Pointer;
begin
  Result:=TObjectListItem(Obj).FPrev;
end;

В интерфейсе дублируются функции, и sas знать не знает что там кроется за Pointer-ом.
Проверку на NIL специально опустил для наглядности.

А так добавляются новые элементы в список:
Код: Выделить всё
function TObjectListHolder.AppendNew: Pointer;
begin
  Result:=TObjectListItem.Create;

  if (FList=nil) then
    begin
      // создали самый первый элемент
      TObjectListItem(Result).FPrev:=TObjectListItem(Result);
      TObjectListItem(Result).FNext:=TObjectListItem(Result);
      FList:=TObjectListItem(Result);
    end
  else
  if (FList.FPrev=FList) then
    begin
      // создали второй элемент в списке - тоже реализация попроще
      FList.FPrev:=TObjectListItem(Result);
      FList.FNext:=TObjectListItem(Result);
      TObjectListItem(Result).FPrev:=FList;
      TObjectListItem(Result).FNext:=FList;
    end
  else
    begin
      // создали очередной элемент в списке - полная реализация
      // вставляем его в конец списка между FList.FPrev и FList и закольцовываем обе связи с 2 сторон
      TObjectListItem(Result).FNext:=FList;
      TObjectListItem(Result).FPrev:=FList.FPrev;
      FList.FPrev:=TObjectListItem(Result);
      TObjectListItem(Result).FPrev.FNext:=TObjectListItem(Result);
    end;
end;
Последний раз редактировалось vasketsov 30 июн 2011, 11:01, всего редактировалось 1 раз.
vasketsov
Специалист
 
Сообщения: 901
Зарегистрирован: 25 июл 2009, 21:15
Благодарил (а): 0 раз.
Поблагодарили: 198 раз.

Re: FlightRadar+SAS

Сообщение vdemidov » 30 июн 2011, 10:55

Зачем этот огород с двунаправленным списком? Чем простой указатель на массив хуже? Все равно будет IObjectListHolder, почему бы ему не возвращать количество и указатель на первый элемент массива?
Чтобы понять программу, вы должны стать одновременно и машиной, и программой.
Аватара пользователя
vdemidov
Гуру
 
Сообщения: 1687
Зарегистрирован: 12 дек 2008, 13:10
Откуда: Киев
Благодарил (а): 191 раз.
Поблагодарили: 157 раз.

Re: FlightRadar+SAS

Сообщение vasketsov » 30 июн 2011, 11:10

vdemidov писал(а):Зачем этот огород с двунаправленным списком?

Ну можно и однонаправленным ограничиться. Будет попроще.

vdemidov писал(а):Чем простой указатель на массив хуже?

Очевидно бедой с перераспределением памяти (сигнал пропал - точка пропала, сигнал появился - точка появилась) и по сути ненужностью. Ничего из того, что требуется от массивов, для протокола взаимодействия не требуется. Идентификацию элементов по номеру в таком массиве не сделать, элементы создаются и удаляются (в том числе пока один отрисовывается, второй может исчезнуть) - всё равно придётся прятаться за абстрактным указателем.

vdemidov писал(а):почему бы ему не возвращать количество и указатель на первый элемент массива?

Очевидно потому что количество в общем случае нафиг никому не нужно.

Тут на самом деле ситуация совершенно обратная. Имея массив, обход его делается через FOR. А цикл FOR работает, когда заранее известно количество элементов. Фактически в данной ситуации массив и for получаются вещью в себе, обосновываемые только необходимостью применения друг друга. А когда происходит отказ от массива, всё сразу встаёт на свои места, цикл получается типа while или repeat, и никаких заранее наложенных ограничений.
vasketsov
Специалист
 
Сообщения: 901
Зарегистрирован: 25 июл 2009, 21:15
Благодарил (а): 0 раз.
Поблагодарили: 198 раз.

Re: FlightRadar+SAS

Сообщение vdemidov » 30 июн 2011, 11:55

Ну внутри плагина пользовать можно все что угодно хоть список, хоть R-tree, хоть хеш-таблицу, а вот в программу лучше отдавать простой интерфейс итератора с двумя методами:
function Next(out AItem: ISASObject): boolean;
procedure Reset;
И программе тогда будет пофигу как вы его реализуете. И тредсейфовость не пострадает, а то в случае списков поддерживать ее это еще та морока.
Чтобы понять программу, вы должны стать одновременно и машиной, и программой.
Аватара пользователя
vdemidov
Гуру
 
Сообщения: 1687
Зарегистрирован: 12 дек 2008, 13:10
Откуда: Киев
Благодарил (а): 191 раз.
Поблагодарили: 157 раз.

Re: FlightRadar+SAS

Сообщение vasketsov » 30 июн 2011, 12:29

vdemidov писал(а):в программу лучше отдавать простой интерфейс итератора с двумя методами:
function Next(out AItem: ISASObject): boolean;
procedure Reset;

Насчёт итератора это верно.
Но чем же лучше такой stateless?
Мало ли из хоста в неколько потоков полезут за разными делами, зачем заставлять плагин хранить для каждого вызывающего текущий элемент?
Уж явно одна фунция вида function Next(AItem: Pointer): Pointer или даже function Next(var AItem: Pointer): Boolean выглядит в самом сасе проще некуда:
var
cur: Pointer;
begin
cur:=nil;
while Next(cur) do
Show(cur);
end;

Причём интерфейс конкретного элемента вообще не надо вводить в оборот, методы Next и Show - это методы как бы всего плагина.
vasketsov
Специалист
 
Сообщения: 901
Зарегистрирован: 25 июл 2009, 21:15
Благодарил (а): 0 раз.
Поблагодарили: 198 раз.

Re: FlightRadar+SAS

Сообщение vdemidov » 30 июн 2011, 19:12

vasketsov писал(а):Причём интерфейс конкретного элемента вообще не надо вводить в оборот, методы Next и Show - это методы как бы всего плагина

Ой развеселили. И что с этим поинтером делать если не вводить интерфейс для итема? А если вводить то нафиг поинтер? Нет. Только интерфейс. Причем скорее всего еще и с указанием GUID ожидаемого интерфейса, что бы в случае изменения API проблем не было.
Чтобы понять программу, вы должны стать одновременно и машиной, и программой.
Аватара пользователя
vdemidov
Гуру
 
Сообщения: 1687
Зарегистрирован: 12 дек 2008, 13:10
Откуда: Киев
Благодарил (а): 191 раз.
Поблагодарили: 157 раз.

Re: FlightRadar+SAS

Сообщение vasketsov » 30 июн 2011, 20:52

vdemidov писал(а):Ой развеселили. И что с этим поинтером делать если не вводить интерфейс для итема?

Мы говорим вообще или про итератор?
А интерфейс тут нафиг не нужен просто потому что Show(obj), реализованная внутри плагина, как раз и будет рисовать через интерфейс хоста. Раз иконки и все прочие параметры-настройки в плагине - он и дергает за ниточки рисования хост. То есть сам хост ровным счётом ничего не делает с данными плагина, он вообще не знает, что там за данные вообще и как их рисовать в частности. Он только умеет обойти все элементы плагина.

vdemidov писал(а):А если вводить то нафиг поинтер?

Зачем "если"?
Поинтер - чтобы раз и навсегда написанный итератор мог работать для любых плагинов вообще. Смысла рамножать тут интерфейсы ровно ноль. Это мегапростой случай. А пойнтер - это единственный валидный тип указателя на произвольную структуру, объект или интерфейс.

vdemidov писал(а):Причем скорее всего еще и с указанием GUID ожидаемого интерфейса, что бы в случае изменения API проблем не было.

Изменения API итератора? Не смешите. Там весь API из одной функции состоит и в случае реализации через Pointer-ы не меняется никогда. Буквально - плагин (ну или в некоторых случаях конкретный интерфейс плагина) либо поддерживает абстрактную процедуру (интерфейс) итератора, либо нет. Не надо всё усложнять сверх меры.
vasketsov
Специалист
 
Сообщения: 901
Зарегистрирован: 25 июл 2009, 21:15
Благодарил (а): 0 раз.
Поблагодарили: 198 раз.

Пред.След.

Вернуться в Раздел для разработчиков программы SAS.Планета

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1