forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   FAQ (http://forum.boolean.name/forumdisplay.php?f=15)
-   -   Контейнер данных (http://forum.boolean.name/showthread.php?t=5730)

impersonalis 12.02.2008 02:05

Контейнер данных
 
Рано или поздно появляется необходимость во всевозможных структурах хранения объектов – списках и т.п. Все те немногочисленные статьи, что до сегодняшнего момента мне попадались. Сводились к подключению сторонних библиотек. На мой же взгляд решение гораздо проще и всё это время, буквально лежало перед глазами. Адекватный перегружаемый интерфейс класса-контейнера с иерархической структурой предоставляет нам трёхмерная квази-модель полностью построенная на пивотах. Сама работа с контейнером сводится в таком случае к командам:
<O> Для организации структуры и работы с ней -
  • CreatePivot ( [parent] )
  • FreeEntity EntityHandle
  • EntityParent entity,parent[,global]
  • GetParent ( entity )
  • CountChildren ( entity )
  • GetChild (entity,index)
<O> Для доступа к информационным полям элемента структуры -
  • NameEntity entity,name$
  • EntityName$ ( entity )
  • Object
  • Handle
<O> Прочие команды.

Рассмотрим пример создания древа. Пример весьма «корявый», но богатый на применение различных функций работы со структурой.
Код:

Graphics3D 800,600,32
SetBuffer BackBuffer()

Local root=CreatePivot()
NameEntity root,"директор"
For i=1 To 3
        NameEntity CreatePivot(root),"руководитель"+Str(i)
        For j=1 To Rand(1,4)
                NameEntity CreatePivot(FindChild(root,"руководитель"+Str(i))),"работник"+Str(j)
        Next
Next


Local a
Local b

Print EntityName(root)
For i=1 To CountChildren(root)
        a=GetChild(root,i)
        Print "->"+EntityName(a)
        For j=1 To CountChildren(a)
                b=GetChild(a,j)
                Print "-->"+EntityName(b)       
        Next
Next
WaitKey()
End

Как дополнительные внутренние поля элементов структуры вы можете использовать иные типовые характеристики Entity: позицию по 3 координатам (3 х 4 байта) и углы вращения (3 переменных со значением от -180 до 180 [весьма проблематичным может оказаться автоматическая коррекция границы]). Их удобно использовать для предварительной идентификации листка древа.
Саму же работу со структурой легко реализовать при помощи рекурсивных функций, что упростит работу с ними и повысит наглядность.
Вот как это может выглядеть:
Код:

Graphics3D 800,600,32
SetBuffer BackBuffer()

Local a
Local b
Local root=CreatePivot()
NameEntity root,"директор"
PositionEntity root,24*5,24*5*500,0
For i=1 To 3
        a=CreatePivot(root)
        NameEntity a,"руководитель"+Str(i)
        PositionEntity a,24*Rnd(6,8),24*Rnd(6,8)*200,0
        For j=1 To Rand(1,4)
                b=CreatePivot(a)
                NameEntity b,"работник"+Str(j)
                PositionEntity b,24*Rnd(8,12),24*Rnd(8,12)*100,0
        Next
Next

Function W(r%,prefix$)
        Print prefix$+EntityName(r)
        Print prefix$+" часов работы "+EntityX(r)+"; зарплата "+EntityY(r)
        Print ""
        prefix$=prefix$+"-"
        For i=1 To CountChildren(r)
                W(GetChild(r,i),prefix)
        Next
End Function


W(root,"")
WaitKey()
End

Для хранения структур вы можете воспользоваться командами Object\Handle – сохраняя\загружая квази-адрес структуры в поле имени пивота.

Минусов подобной организации я нашёл только два:

:wallbash: Необходимость инициализации 3D-режима графики. Это, в общем-то, не так болезненно (никто вас не принуждает создавать камеры и рендерить сцену). Кроме того уже само название среды – Blitz3D – подразумевает, что вы пишете программу работы с 3х-мерной графикой, таким образом – для большинства программ применение таких структур не меняет режим графики.

:wallbash: Дополнительные расходы на память. Что есть – то есть. Однако подумайте об удобстве, которое вы на мой взгляд получаете.

:imp:

avel 12.02.2008 03:22

Ответ: Контейнер данных
 
хм. интересно. правда, как-то непривычно такое их использование...

tormoz 12.02.2008 03:44

Ответ: Контейнер данных
 
Супер-оригинально
Респект

До этого я использовал пивоты для упрощения расчетов вческих операций с 3д объектами (как не странно это работает намного быстрее математических расчетов)
Например, вместо того, чтобы писать километровые расчеты с матрицами, просто ставим пивот, вращаем, двигаем куда надо, потом снимаем с него готовые значения.

HolyDel 12.02.2008 11:01

Ответ: Контейнер данных
 
полностью согласен с tormoz'ом, замечательная идея!
от себя могу посоветовать, что если все же будет камера, и будет рендер (обычно они есть), то лучше скрывать пивот (ну и что, что ничего итак не видно), наблюдается небольшое повышение производительности:

Код:

Graphics3D 1024,768,32,2

n=10000
Dim ps(n)
For i=1 To n
        ps(i)=CreatePivot()
        HideEntity ps(i)
Next

cam=CreateCamera()

frame=0
a_time=MilliSecs()
While Not KeyDown(1)

        frame=frame+1
        If a_time<MilliSecs()-1000
                fps=frame
                frame=0
                a_time=MilliSecs()
        EndIf
       
        RenderWorld
        Text 10,10,fps
        Flip 0
Wend

закоментите строчку hideentity() и сравните с раскоменченой.

Raiter 12.02.2008 18:29

Ответ: Контейнер данных
 
Респект за оригинальность!


Часовой пояс GMT +4, время: 11:38.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot