OberonCore https://forum.oberoncore.ru/ |
|
Rider - Scroller разделение https://forum.oberoncore.ru/viewtopic.php?f=6&t=361 |
Страница 1 из 1 |
Автор: | Сергей Губанов [ Четверг, 04 Январь, 2007 14:50 ] |
Заголовок сообщения: | Rider - Scroller разделение |
Райдеры (rider), т. е. считыватели и записыватели (reader и writer) могут быть либо последовательными (не позиционируемые), либо с произвольным доступом (позиционируемые). Программист может испытать затруднение при описании их типов, а именно не ясно стоит ли каждый раз заводить по два разных типа райдеров (позиционируемые и не позиционируемые) или же включить методы позиционирования (GetPosition, SetPosition,...) в один тип, но например выставлять некий булевский флаг возможности их использования. В первом случае получается слишком много типов (по 2 reader и по 2 writer), а во втором случае методы позиционирования иногда будут лишними, а тип громоздким. Предлагаю иное решение. Вместо того чтобы включать методы позиционирования в типы reader и writer можно обзавестись типом скроллер (scroller), который и будет нести ответственность за прокрутку райдеров: Код: Rider = POINTER TO ABSTRACT RECORD (r: Rider) Available (): LONGINT, NEW, ABSTRACT END; Scroller = POINTER TO ABSTRACT RECORD (s: Scroller) MinPosition (): LONGINT, NEW, ABSTRACT; (s: Scroller) MaxPosition (): LONGINT, NEW, ABSTRACT; (s: Scroller) GetPosition (r: Rider): LONGINT, NEW, ABSTRACT; (s: Scroller) SetPosition (r: Rider; position: LONGINT), NEW, EMPTY END; где метод Available (): LONGINT показывает сколько позиций доступно для продвижения вперёд, т. е. для reader - сколько доступно для считывания и для writer - сколько доступно для записи. Бинарные считыватель и записыватель, при этом, есть просто: Код: Reader = POINTER TO ABSTRACT RECORD (Rider) (r: Reader) ReadByte (OUT a: BYTE), NEW, ABSTRACT; (r: Reader) ReadBytes (OUT a: ARRAY OF BYTE; offset, count: INTEGER), NEW, ABSTRACT END; Writer = POINTER TO ABSTRACT RECORD (Rider) (w: Writer) WriteByte (a: BYTE), NEW, ABSTRACT; (w: Writer) WriteBytes (IN a: ARRAY OF BYTE; offset, count: INTEGER), NEW, ABSTRACT END; Рассмотрим тип объекта-буфера. Кроме считывателей и записывателей буфер должен будет предоставлять ещё и скроллер: Код: Buffer = POINTER TO ABSTRACT RECORD (b: Buffer) NewReader (old: Reader): Reader, NEW, ABSTRACT; (b: Buffer) NewWriter (old: Writer): Writer, NEW, ABSTRACT; (b: Buffer) Scroller (): Scroller, NEW, ABSTRACT END; А вот, например, тип канал (channel) скроллера своих райдеров предоставлять не будет - они же у него не позиционируемые: Код: Channel = POINTER TO ABSTRACT RECORD
(c: Channel) Reader (): Reader, NEW, ABSTRACT; (c: Channel) Writer (): Writer, NEW, ABSTRACT; END; Позиционируемость райдера зависит от его носителя (carrier). Носитель либо предоставляет скроллер для своих райдеров либо не предоставляет, вот и всё. |
Автор: | Илья Ермаков [ Четверг, 04 Январь, 2007 15:00 ] |
Заголовок сообщения: | |
По-моему, красивая и полезная идея! |
Автор: | Александр Ильин [ Четверг, 04 Январь, 2007 19:33 ] |
Заголовок сообщения: | |
Да, идея интересная, решает определенные проблемы. Не совсем понятно, правда, что должен возвращать метод Writer.Availabe? Объем свободного места на диске? : ) |
Автор: | Cardinal [ Четверг, 04 Январь, 2007 20:34 ] |
Заголовок сообщения: | Re: Rider - Scroller разделение |
2 Сергей Губанов Мне кажется лишним этот тип "скроллер". Для меня - тип райдера определяется целью, то есть где-то он должен быть только последовательным, а где-то - только с произвольным доступом. Я пока не вижу пользы... пока что лишняя сущность |
Автор: | Сергей Губанов [ Четверг, 04 Январь, 2007 21:56 ] |
Заголовок сообщения: | |
Александр Ильин писал(а): ...что должен возвращать метод Writer.Availabe? Объем свободного места на диске? : )
Да, не плохо бы . Вообще, если места много, то можно возвращать достаточно произвольное большое число. Метод WriteBytes может копировать содержимое в какие-либо внутренние буферы. В таком случае Writer.Availabe должен предупредить о существующем ограничении - сколько байтов можно записать за один раз. То есть не сколько вообще места доступно, а сколько можно запихнуть байтов за один присест. |
Автор: | Сергей Губанов [ Воскресенье, 07 Январь, 2007 15:16 ] |
Заголовок сообщения: | Re: Rider - Scroller разделение |
Сергей Губанов писал(а): Код: Scroller = POINTER TO ABSTRACT RECORD (s: Scroller) MinPosition (): LONGINT, NEW, ABSTRACT; (s: Scroller) MaxPosition (): LONGINT, NEW, ABSTRACT; (s: Scroller) GetPosition (r: Rider): LONGINT, NEW, ABSTRACT; (s: Scroller) SetPosition (r: Rider; position: LONGINT), NEW, EMPTY END; Можно немножко усовершенствовать. Объект Scroller можно сделать не имеющим состояния синглетоном (обслуживающим все райдеры из своего модуля) если передавать райдер во все его методы: Код: Scroller = POINTER TO ABSTRACT RECORD
(s: Scroller) MinPosition (r: Rider): LONGINT, NEW, ABSTRACT; (s: Scroller) MaxPosition (r: Rider): LONGINT, NEW, ABSTRACT; (s: Scroller) GetPosition (r: Rider): LONGINT, NEW, ABSTRACT; (s: Scroller) SetPosition (r: Rider; position: LONGINT), NEW, EMPTY END; Ведь вся эта информация всё равно целиком содержится в райдере. То есть на один модуль фактически будет только один объект Scroller. |
Автор: | Сергей Губанов [ Среда, 12 Декабрь, 2007 13:15 ] |
Заголовок сообщения: | Re: Rider - Scroller разделение |
Ещё одно усовершенствование. Если в райдер добавить некий абстрактный локатор: Код: public abstract class Rider { public virtual object Locator { get { return null; } } } public abstract class Writer: Rider { public abstract void WriteByte (byte b); public abstract void WriteBytes (byte[] bytes, int offset, int count); public virtual void WriteBoolean (bool x) ... } public abstract class Reader: Rider { public abstract long Available { get; } public abstract byte ReadByte (); public abstract void ReadBytes (byte[] bytes, int offset, int count); public virtual bool ReadBool () ... } public abstract class Scroller { public virtual long MinPosition (Rider r) { return 0; } public virtual long MaxPosition (Rider r) { return System.Int64.MaxValue; } public abstract long GetPosition (Rider r); public abstract void SetPosition (Rider r, long position); } public abstract class Buffer { public abstract long Length { get; } public abstract Scroller Scroller { get; } public abstract Writer NewWriter (); public abstract Reader NewReader (); } то реализация скроллера упростится: Код: private sealed class TheScroller: Scroller { private static Locator GetLocator (Rider r) { Locator loc = r.Locator as Locator; if (loc != null) return loc; else throw new System.Exception("Alien rider."); } public override long MaxPosition (Rider r) { return GetLocator(r).buffer.length; } public override long GetPosition (Rider r) { return GetLocator(r).Position; } public override void SetPosition (Rider r, long position) { GetLocator(r).Position = position; } } Извините за C#, в Component Pascal это транслируется практически один в один. |
Автор: | Илья Ермаков [ Воскресенье, 16 Декабрь, 2007 15:05 ] |
Заголовок сообщения: | Re: Rider - Scroller разделение |
Сергей, сообщаю, что давно понравившуюся Вашу идею я наконец начинаю применять |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |