Kaynağa Gözat

SVI Переделка кода

SVI 1 hafta önce
ebeveyn
işleme
fe764b4087

+ 0 - 7
lev0/types/iactor.go

@@ -1,7 +0,0 @@
-package types
-
-// IActor -- интерфейс актора
-type IActor interface {
-	IElemBase
-	IElemGroupLink
-}

+ 0 - 11
lev0/types/idrawer.go

@@ -1,11 +0,0 @@
-package types
-
-import (
-	svg "github.com/ajstarks/svgo"
-)
-
-// IDrawer -- интерфейс рисовальщик элемента
-type IDrawer interface {
-	// Draw -- рисует себя на холсте
-	Draw(canvas *svg.SVG)
-}

+ 10 - 0
lev0/types/ielem_actor.go

@@ -0,0 +1,10 @@
+package types
+
+// IElemActor -- интерфейс актора
+type IElemActor interface {
+	IElemBase
+	// Name -- имя актора
+	Name() string
+	// GroupLink -- возвращает группу ссылок актора
+	GroupLink() IElemGroupLink
+}

+ 3 - 1
lev0/types/ielem_base.go

@@ -12,6 +12,8 @@ type IElemBase interface {
 	Id() alias.Id
 	// SelfCheck -- самопроверка базового элемента
 	SelfCheck()
+	// InvarCheck -- проверка инвариантов
+	InvarCheck() string
 	// Coord -- возвращает координаты метки
-	Coord() ICoord
+	// Coord() ICoord
 }

+ 4 - 4
lev0/types/ielem_link.go

@@ -2,13 +2,13 @@ package types
 
 // IElemLink -- интерфейс связи между объектами
 type IElemLink interface {
-	IElemBase
+	IViewLabel
 	// Src -- возвращает источник связи
 	Src() IElemBase
 	// Dst -- возвращает получателя связи
 	Dst() IElemBase
-	// Label -- метка связи
-	Label() IElemLabel
 	// CoordEnd -- координаты конца связи
-	CoordEnd() ICoord
+	CoordEnd() IViewCoord
+	// TypeLink -- тип связи
+	TypeLink() string
 }

+ 1 - 1
lev0/types/ielem_use_case.go

@@ -8,5 +8,5 @@ type IElemUseCase interface {
 	// Links -- ссылки вариантов использования
 	Links() map[alias.Id]IElemLink
 	// Label -- метка варианта использования
-	Label() IElemLabel
+	Label() IViewLabel
 }

+ 1 - 1
lev0/types/ielem_use_group.go

@@ -8,5 +8,5 @@ type IElemUseGroup interface {
 	// Links -- заглушка на связи между объектами
 	Links() []alias.Id
 	// Size -- возвращает размер
-	Size() ISize
+	Size() IViewSize
 }

+ 13 - 0
lev0/types/imap_drawer.go

@@ -0,0 +1,13 @@
+package types
+
+import (
+	svg "github.com/ajstarks/svgo"
+)
+
+// IMapDrawer -- интерфейс словаря для отрисовки
+type IMapDrawer interface {
+	// Draw -- рисует карту
+	Draw(canvas *svg.SVG)
+	// LstDrawers -- возвращает список отрисовщиков
+	LstDrawers() []IMapDrawer
+}

+ 0 - 7
lev0/types/iserv_http.go

@@ -1,7 +0,0 @@
-package types
-
-// IServHttp -- интерфейс http-сервиса
-type IServHttp interface {
-	// Run -- запуск http-сервиса
-	Run() error
-}

+ 12 - 0
lev0/types/iview_base.go

@@ -0,0 +1,12 @@
+package types
+
+import svg "github.com/ajstarks/svgo"
+
+// IViewBase -- интерфейс базовой схемы
+type IViewBase interface {
+	IElemBase
+	// Coord -- координаты элемента
+	Coord() IViewCoord
+	// Draw -- рисование элемента
+	Draw(canvas *svg.SVG)
+}

+ 2 - 2
lev0/types/icoord.go → lev0/types/iview_coord.go

@@ -2,8 +2,8 @@ package types
 
 import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 
-// ICoord -- интерфейс координат
-type ICoord interface {
+// IViewCoord -- интерфейс координат
+type IViewCoord interface {
 	// X -- возвращает координату X
 	X() alias.CoordX
 	// Y -- возвращает координату Y

+ 4 - 5
lev0/types/ielem_label.go → lev0/types/iview_label.go

@@ -4,14 +4,13 @@ import (
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 )
 
-// IElemLabel -- надпись
-type IElemLabel interface {
-	IElemBase
-	IDrawer
+// IViewLabel -- надпись
+type IViewLabel interface {
+	IViewBase
 	// Get -- возвращает метку
 	Get() alias.Label
 	// String -- возвращает строку
 	String() string
 	// Offset -- возвращает смещение метки
-	Offset() IOffset
+	Offset() IViewOffset
 }

+ 2 - 2
lev0/types/ioffset.go → lev0/types/iview_offset.go

@@ -2,8 +2,8 @@ package types
 
 import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 
-// IOffset -- интерфейс смещения
-type IOffset interface {
+// IViewOffset -- интерфейс смещения
+type IViewOffset interface {
 	// X -- возвращает смещение X
 	X() alias.CoordX
 	// Y -- возвращает смещение Y

+ 2 - 2
lev0/types/isize.go → lev0/types/iview_size.go

@@ -2,8 +2,8 @@ package types
 
 import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 
-// ISize -- интерфейс для размера
-type ISize interface {
+// IViewSize -- интерфейс для размера
+type IViewSize interface {
 	// Get -- возвращает размер
 	Get() (alias.SizeX, alias.SizeY)
 	// Int -- возвращает размер

+ 1 - 1
lev1/coord/coord.go

@@ -13,7 +13,7 @@ type Coord struct {
 }
 
 // NewCoord -- возвращает новую координаты
-func NewCoord(x alias.CoordX, y alias.CoordY) types.ICoord {
+func NewCoord(x alias.CoordX, y alias.CoordY) types.IViewCoord {
 	sf := &Coord{
 		X_: x,
 		Y_: y,

+ 7 - 7
lev1/elem_base/elem_base.go

@@ -13,7 +13,7 @@ import (
 type ElemBase struct {
 	Id_    alias.Id     `yaml:"id"`    // Идентификатор объекта
 	Type_  alias.Type   `yaml:"type"`  // Тип объекта
-	Coord_ types.ICoord `yaml:"coord"` // Координаты элемента
+	Coord_ types.IViewCoord `yaml:"coord"` // Координаты элемента
 }
 
 var (
@@ -21,7 +21,7 @@ var (
 )
 
 // NewElemBase -- возвращает новый базовый объект
-func NewElemBase(coord types.ICoord, type_ alias.Type) types.IElemBase {
+func NewElemBase(coord types.IViewCoord, type_ alias.Type) types.IElemBase {
 	sf := &ElemBase{
 		Coord_: coord,
 		Id_:    alias.Id(uuid.New().String()),
@@ -31,11 +31,11 @@ func NewElemBase(coord types.ICoord, type_ alias.Type) types.IElemBase {
 	return sf
 }
 
-// Coord -- возвращает координаты элемента
-//
-//go:fix inline
-func (sf *ElemBase) Coord() types.ICoord {
-	return sf.Coord_
+
+// InvarCheck -- проверяет инварианты базового элемента
+func (sf *ElemBase) InvarCheck() string {
+	hassert(false, "ElemBase.InvarCheck(): id:%v, not implemented", sf.Id_)
+	return ""
 }
 
 // Type -- возвращает тип объекта

+ 3 - 3
lev1/elem_label/elem_label.go

@@ -14,7 +14,7 @@ import (
 type ElemLabel struct {
 	types.IElemBase
 	Val_    alias.Label   `yaml:"val"`    // Метка для вывода
-	Offset_ types.IOffset `yaml:"offset"` // Смещение метки
+	Offset_ types.IViewOffset `yaml:"offset"` // Смещение метки
 }
 
 var (
@@ -22,7 +22,7 @@ var (
 )
 
 // NewElemLabel -- возвращает новую метку
-func NewElemLabel(label alias.Label, coord types.ICoord, offset types.IOffset) types.IElemLabel {
+func NewElemLabel(label alias.Label, coord types.IViewCoord, offset types.IViewOffset) types.IViewLabel {
 	sf := &ElemLabel{
 		IElemBase: elem_base.NewElemBase(coord, "elem_label"),
 		Val_:      label,
@@ -66,6 +66,6 @@ func (sf *ElemLabel) Get() alias.Label {
 // Offset -- возвращает смещение метки
 //
 //go:fix inline
-func (sf *ElemLabel) Offset() types.IOffset {
+func (sf *ElemLabel) Offset() types.IViewOffset {
 	return sf.Offset_
 }

+ 19 - 11
lev1/elem_link/elem_link.go

@@ -12,12 +12,12 @@ import (
 
 // ElemLink -- связь между объектами
 type ElemLink struct {
-	types.IElemBase
-	CoordEnd_ types.ICoord    `yaml:"coord_end"` // Координаты второй точки
+	types.IViewLabel
+	CoordEnd_ types.IViewCoord    `yaml:"coord_end"` // Координаты второй точки
 	Src_      types.IElemBase `yaml:"src"`       // Источник координат
 	Dst_      types.IElemBase `yaml:"dst"`       // Получатель координат
 
-	TypeLink_ string `yaml:"typeLink"` // Тип связи
+	TypeLink_ string `yaml:"type_link"` // Тип связи
 }
 
 var (
@@ -25,32 +25,40 @@ var (
 )
 
 // NewElemLink -- возвращает новую связь
-func NewElemLink(elemBase types.IElemBase, coordEnd types.ICoord,
+func NewElemLink(elemLabel types.IViewLabel, coordEnd types.IViewCoord,
 	src, dst types.IElemBase, typeLink string) types.IElemLink {
 
 	sf := &ElemLink{
-		IElemBase: elemBase,
+		IViewLabel: elemLabel,
 		CoordEnd_: coordEnd,
 		Src_:      src,
 		Dst_:      dst,
 		TypeLink_: typeLink,
 	}
+	sf.SelfCheck()
 	return sf
 }
 
 // SelfCheck -- самопроверка элемента
 func (sf *ElemLink) SelfCheck() {
-	sf.IElemBase.SelfCheck()
+	sf.IViewLabel.SelfCheck()
 	hassert(sf.CoordEnd_ != nil, "ElemLink.SelfCheck(): id=%v, CoordEnd_ == nil", sf.Id())
 	hassert(sf.Src_ != nil, "ElemLink.SelfCheck(): id=%v, Src_ == nil", sf.Id())
 	hassert(sf.Dst_ != nil, "ElemLink.SelfCheck(): id=%v, Dst_ == nil", sf.Id())
 	hassert(sf.TypeLink_ != "", "ElemLink.SelfCheck(): id=%v, TypeLink_ is empty", sf.Id())
 }
 
+// TypeLink -- тип связи
+//
+//go:fix inline
+func (sf *ElemLink) TypeLink() string {
+	return sf.TypeLink_
+}
+
 // CoordEnd -- координаты конца связи
 //
 //go:fix inline
-func (sf *ElemLink) CoordEnd() types.ICoord {
+func (sf *ElemLink) CoordEnd() types.IViewCoord {
 	return sf.CoordEnd_
 }
 
@@ -85,12 +93,12 @@ func (sf *ElemLink) checkDst() string {
 	// Вычислить на допустимые типы для получателя
 	switch sf.Dst_.Type() {
 	case cons.TypeUseActor:
-		actor, isOk := sf.Dst_.(types.IActor)
+		actor, isOk := sf.Dst_.(types.IElemActor)
 		if !isOk {
 			return fmt.Sprintf("Недопустимый тип получателя(%q)\nтип=%q\n", sf.Dst_.Id(), sf.Dst_.Type())
 		}
 		isOk = false
-		for _, id := range actor.Links() {
+		for _, id := range actor.GroupLink().Links() {
 			if id == sf.Id() {
 				isOk = true
 				break
@@ -142,8 +150,8 @@ func (sf *ElemLink) checkSrc() string {
 	switch sf.Src_.Type() {
 	case cons.TypeUseActor:
 		isOk := false
-		actor := sf.Src_.(types.IActor)
-		for _, id := range actor.Links() { // Проверка на взаимность
+		actor := sf.Src_.(types.IElemActor)
+		for _, id := range actor.GroupLink().Links() { // Проверка на взаимность
 			if id == sf.Id() {
 				isOk = true
 				break

+ 2 - 2
lev1/elem_use_case/elem_use_case.go

@@ -13,7 +13,7 @@ import (
 // UseCase -- вариант использования
 type UseCase struct {
 	types.IElemBase
-	Size_  types.ISize                       `yaml:"size"`
+	Size_  types.IViewSize                       `yaml:"size"`
 	Links_ map[alias.Id]types.IElemGroupLink `yaml:"links"` // Список ссылок
 }
 
@@ -22,7 +22,7 @@ var (
 )
 
 // NewUseCase -- возвращает новый вариант использования
-func NewUseCase(elemBase types.IElemBase, size types.ISize,
+func NewUseCase(elemBase types.IElemBase, size types.IViewSize,
 	links map[alias.Id]types.IElemGroupLink) *UseCase {
 	// id := elemBase.Id()
 	// _links0, isOk := elemBase.Elem_["links"]

+ 3 - 3
lev1/elem_use_group/elem_use_group.go

@@ -10,7 +10,7 @@ import (
 // UseGroup -- группа вариантов использования
 type UseGroup struct {
 	types.IElemBase
-	Size_ types.ISize
+	Size_ types.IViewSize
 }
 
 var (
@@ -18,7 +18,7 @@ var (
 )
 
 // NewUseGroup -- возвращает новую группу вариант использования
-func NewUseGroup(elemBase types.IElemBase, size types.ISize) types.IElemUseGroup {
+func NewUseGroup(elemBase types.IElemBase, size types.IViewSize) types.IElemUseGroup {
 	sf := &UseGroup{
 		IElemBase: elemBase,
 		Size_:     size,
@@ -30,7 +30,7 @@ func NewUseGroup(elemBase types.IElemBase, size types.ISize) types.IElemUseGroup
 // Size -- возвращает размер
 //
 //go:fix inline
-func (sf *UseGroup) Size() types.ISize {
+func (sf *UseGroup) Size() types.IViewSize {
 	return sf.Size_
 }
 

+ 1 - 1
lev1/offset/offset.go

@@ -13,7 +13,7 @@ type Offset struct {
 }
 
 // NewOffset -- возвращает новое смещение
-func NewOffset(x alias.CoordX, y alias.CoordY) types.IOffset {
+func NewOffset(x alias.CoordX, y alias.CoordY) types.IViewOffset {
 	sf := &Offset{
 		X_: x,
 		Y_: y,

+ 1 - 1
lev1/size/size.go

@@ -20,7 +20,7 @@ var (
 )
 
 // NewSize -- возвращает новый размер
-func NewSize(w alias.SizeX, h alias.SizeY) types.ISize {
+func NewSize(w alias.SizeX, h alias.SizeY) types.IViewSize {
 	sf := &Size{
 		W_: w,
 		H_: h,

+ 9 - 25
lev1/view_link/view_link.go

@@ -5,7 +5,6 @@ import (
 	svg "github.com/ajstarks/svgo"
 	"gitp78su.ipnodns.ru/svi/kern/v3"
 
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
 )
 
@@ -28,38 +27,23 @@ func NewViewLink(useLink types.IElemLink) *ViewLink {
 }
 
 // Draw -- рисует связь между объектами
-func (sf *ViewLink) Draw(canvas *svg.SVG, mapDrawer map[alias.Id]types.IDrawer) {
-	x, y := sf.Label().Coord().Int()
-	_x, _y = sf.CoordEnd().Coord()
-	x1 := int(_x)
-	y1 := int(_y)
-	_x, _y = sf.UseLink_.ElemBase_.Label_.Offset_.Offset()
-	offX := int(_x)
-	offY := int(_y)
+func (sf *ViewLink) Draw(canvas *svg.SVG) {
+	x, y := sf.Coord().Int()
+	x1, y1 := sf.CoordEnd().Int()
+	offX, offY := sf.Offset().Int()
 	// Линия
 	canvas.Line(x, y, x1, y1, "stroke:black;stroke-width:1")
-	strLabel := string(sf.UseLink_.ElemBase_.Label_.Val_)
+	strLabel := sf.String()
 	if strLabel != "" {
 		canvas.Text(x+offX, y+offY, strLabel, "font-size: 12px; font-family: Courier; fill: black")
 	}
-	strTypeLink := string(sf.UseLink_.TypeLink_)
-	if strTypeLink != "" {
-		canvas.Text(x+offX, y+offY+12, "<<"+strTypeLink+">>", "font-size: 12px; font-family: Courier; fill: black")
+	if sf.TypeLink() != "" {
+		canvas.Text(x+offX, y+offY+12, "<<"+sf.TypeLink()+">>", "font-size: 12px; font-family: Courier; fill: black")
 	}
-	if msgErr := sf.UseLink_.ElemBase_.Check(mapDrawer); msgErr != "" { // Проверка на правильность
+	if msgErr := sf.Check(); msgErr != "" { // Проверка на правильность
 		canvas.Group("Ошибка")
 		canvas.Title(msgErr)
 		canvas.Image(x-20+offX, y-20+offY, 16, 16, "/static/img/warning.png")
-		canvas.Gend() // Group end
 	}
-}
-
-// SrcId -- возвращает источник связи
-func (sf *ViewLink) SrcId() alias.Id {
-	return sf.Src_
-}
-
-// DstId -- возвращает получателя связи
-func (sf *ViewLink) DstId() alias.Id {
-	return sf.Dst_
+	canvas.Gend() // Group end
 }

+ 1 - 1
lev1/view_use_case/view_use_case.go

@@ -10,7 +10,7 @@ import (
 // ViewUseCase -- вариант использования
 type ViewUseCase struct {
 	types.IElemUseCase
-	Size_ types.ISize
+	Size_ types.IViewSize
 }
 
 

+ 0 - 0
lev2/mod_http/index.html → lev2/engine_http/index.html


+ 26 - 78
lev2/mod_http/serv_http.go → lev2/engine_http/serv_http.go

@@ -1,15 +1,17 @@
-// package mod_http -- http-модуль для архитектуры
-package mod_http
+// package mod_http -- http-движок для архитектуры
+package engine_http
 
 import (
 	"bytes"
 	_ "embed"
-	"encoding/json"
 	"fmt"
 	"time"
 
 	svg "github.com/ajstarks/svgo"
 	"github.com/gofiber/fiber/v2"
+	"gitp78su.ipnodns.ru/svi/kern/v3"
+	"gitp78su.ipnodns.ru/svi/kern/v3/kc/log_buf"
+	"gitp78su.ipnodns.ru/svi/kern/v3/krn/ktypes"
 	"gopkg.in/yaml.v3"
 
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
@@ -17,14 +19,7 @@ import (
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
 	"gitp78su.ipnodns.ru/svi/goarch/lev1/coord"
 	"gitp78su.ipnodns.ru/svi/goarch/lev1/size"
-	"gitp78su.ipnodns.ru/svi/goarch/lev1/view_use_case"
 	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/canvas"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_actor"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_link"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_use_group"
-	"gitp78su.ipnodns.ru/svi/kern/v3"
-	"gitp78su.ipnodns.ru/svi/kern/v3/kc/log_buf"
-	"gitp78su.ipnodns.ru/svi/kern/v3/krn/ktypes"
 )
 
 //go:embed index.html
@@ -40,24 +35,25 @@ func (sf *CanvasSize) String() string {
 	return fmt.Sprintf("w:%v; h:%v", sf.SizeX_, sf.SizeY_)
 }
 
-// ModHttp -- http-модуль для архитектуры
-type ModHttp struct {
+// EngineHttp -- http-движок для архитектуры
+type EngineHttp struct {
 	// fibApp     *fiber.App
 	kCtx       ktypes.IKernelCtx
 	log        ktypes.ILogBuf
-	diaMode    string       // Режим диаграммы
-	oldBinArch []byte       // Кеш старой архитектуры
-	canvSize   CanvasSize   // Размер холста
-	size       types.ISize  // Размер холста в его координатах
-	pos        types.ICoord // Координаты холста
+	diaMode    string           // Режим диаграммы
+	oldBinArch []byte           // Кеш старой архитектуры
+	canvSize   CanvasSize       // Размер холста
+	size       types.IViewSize  // Размер холста в его координатах
+	pos        types.IViewCoord // Координаты холста
+	mapDrawer  types.IMapDrawer // Словарь отрисовщиков
 }
 
-// NewModHttp -- возвращает новый сервис
-func NewModHttp() *ModHttp {
+// NewEngineHttp -- возвращает новый движок HTTP
+func NewEngineHttp() *EngineHttp {
 	optTerm := log_buf.OptIsTerm(true)
-	optPref := log_buf.OptPrefix("ModHttp")
+	optPref := log_buf.OptPrefix("EngineHttp")
 	log := log_buf.NewLogBuf(optTerm, optPref)
-	sf := &ModHttp{
+	sf := &EngineHttp{
 		kCtx:    kern.GetKernelCtx(),
 		log:     log,
 		diaMode: cons.ModeUseCase,
@@ -84,7 +80,7 @@ type FormArch struct {
 }
 
 // Устанавливает размер холста
-func (sf *ModHttp) postSetCanvasSize(ctx *fiber.Ctx) error {
+func (sf *EngineHttp) postSetCanvasSize(ctx *fiber.Ctx) error {
 	err := ctx.BodyParser(&sf.canvSize)
 	if err != nil {
 		sf.log.Err("postSetCanvasSize(): on body parser, err=\n\t%v", err)
@@ -104,7 +100,7 @@ func (sf *ModHttp) postSetCanvasSize(ctx *fiber.Ctx) error {
 }
 
 // Возвращает новый холст
-func (sf *ModHttp) canvas(wr *bytes.Buffer, lstElem []map[string]interface{}) (*svg.SVG, error) {
+func (sf *EngineHttp) canvas(wr *bytes.Buffer, lstElem []map[string]interface{}) (*svg.SVG, error) {
 	var (
 		elem         map[string]interface{}
 		isFind, isOk bool
@@ -136,7 +132,7 @@ func (sf *ModHttp) canvas(wr *bytes.Buffer, lstElem []map[string]interface{}) (*
 }
 
 // По запросу парсит, что получилось -- обновляет архитектуру
-func (sf *ModHttp) postArch(ctx *fiber.Ctx) error {
+func (sf *EngineHttp) postArch(ctx *fiber.Ctx) error {
 	form := &FormArch{}
 	if err := ctx.BodyParser(form); err != nil {
 		return ctx.SendString(fmt.Sprintf("ServHttp.archPost(): in BodyParser, err=<br>%v", err))
@@ -157,7 +153,7 @@ func (sf *ModHttp) postArch(ctx *fiber.Ctx) error {
 	}
 	switch sf.diaMode {
 	case cons.ModeUseCase: // режим вариантов использования
-		if err := sf.useCase(canvas, mapElem); err != nil {
+		if err := sf.useCase(canvas); err != nil {
 			return ctx.SendString(fmt.Sprintf("ServHttp.archPost(): in useCase, err=<br>%v", err))
 		}
 	default: // неизвестный режим
@@ -170,69 +166,21 @@ func (sf *ModHttp) postArch(ctx *fiber.Ctx) error {
 }
 
 // Формирует варианты использования
-func (sf *ModHttp) useCase(canvas *svg.SVG, lstElem []map[string]interface{}) error {
-	mapDraw := make(map[alias.Id]types.IDrawer)
-	for _, elem := range lstElem {
-		_id, isOk := elem["id"]
-		if !isOk {
-			return fmt.Errorf("ServHttp.useCase(): field 'id' not found<br>%#+v", elem)
-		}
-		id0, isOk := _id.(string)
-		if !isOk {
-			return fmt.Errorf("ServHttp.useCase(): field 'id'(%T, %+v) not alias.Id", _id, _id)
-		}
-		id := alias.Id(id0)
-		if id == "" {
-			return fmt.Errorf("ServHttp.useCase(): id=%q, elem is empty<br>%#+v", id, elem)
-		}
-		_, isOk = mapDraw[id]
-		if isOk {
-			return fmt.Errorf("ServHttp.useCase(): id=%q already exists", id)
-		}
-		binElem, _ := json.MarshalIndent(elem, "", " ")
-		_type, isOk := elem["type"]
-		if !isOk {
-			return fmt.Errorf("ServHttp.useCase(): id=%q, field 'type' not found<br>%+v", id, string(binElem))
-		}
-		strType, isOk := _type.(string)
-		if !isOk {
-			return fmt.Errorf("ServHttp.useCase(): id=%q, field 'type'(%+v) not string<br>%+v", id, _type, string(binElem))
-		}
-		var (
-			drawer types.IDrawer
-		)
-		switch strType {
-		case cons.TypeUseActor: // Нарисовать актора
-			view_actor.NewViewActor(actor, elem)
-		case cons.TypeUseCase: // Нарисовать вариант использования
-			drawer = view_use_case.NewViewUseCase(useCase, elem)
-		case cons.TypeUseLink: // Нарисовать связь
-			drawer = view_link.NewViewLink(useLink)
-		case cons.TypeUseGroup: // Нарисовать группу вариантов использования
-			drawer = view_use_group.NewViewUseGroup(useGroup, elem)
-		}
-		if drawer != nil {
-			mapDraw[id] = drawer
-			sf.log.Debug("useCase(): id=%q, elem=\n%v\n", id, elem)
-		}
-	}
-	for _, drawer := range mapDraw {
-		switch drawer.(type) {
-		case types.IElemLink:
-		}
-		drawer.Draw(canvas, mapDraw)
+func (sf *EngineHttp) useCase(canvas *svg.SVG) error {
+	for _, elem := range sf.mapDrawer.LstDrawers() {
+		elem.Draw(canvas)
 	}
 	return nil
 }
 
 // Возвращает картинку архитектуры
-func (sf *ModHttp) postSetModeUseCase(ctx *fiber.Ctx) error {
+func (sf *EngineHttp) postSetModeUseCase(ctx *fiber.Ctx) error {
 	sf.diaMode = cons.ModeUseCase
 	return ctx.SendString("[mode='" + sf.diaMode + "']")
 }
 
 // Возвращает главную страницу сервиса
-func (sf *ModHttp) getIndex(ctx *fiber.Ctx) error {
+func (sf *EngineHttp) getIndex(ctx *fiber.Ctx) error {
 	ctx.Response().Header.Set("Content-Type", "text/html")
 	return ctx.Send(indexHtml)
 }

+ 1 - 1
lev2/lev2.go

@@ -1,2 +1,2 @@
-// package lev2 -- уровень модулей
+// package lev2 -- уровень движков и клиентов
 package lev2

+ 5 - 5
lev3/service/service.go

@@ -2,7 +2,7 @@
 package service
 
 import (
-	"gitp78su.ipnodns.ru/svi/goarch/lev2/mod_http"
+	"gitp78su.ipnodns.ru/svi/goarch/lev2/engine_http"
 	"gitp78su.ipnodns.ru/svi/kern/v3"
 	"gitp78su.ipnodns.ru/svi/kern/v3/krn/ktypes"
 	. "gitp78su.ipnodns.ru/svi/kern/v3/krn/ktypes"
@@ -10,8 +10,8 @@ import (
 
 // Service -- тип сервиса
 type Service struct {
-	kCtx    IKernelCtx
-	modHttp *mod_http.ModHttp
+	kCtx       IKernelCtx
+	engineHttp *engine_http.EngineHttp
 }
 
 // NewService -- возвращает новый сервис
@@ -19,8 +19,8 @@ func NewService() *Service {
 	kCtx := kern.GetKernelCtx()
 	kCtx.Set("monolitName", "SviArch", "NewService()")
 	sf := &Service{
-		kCtx:    kern.GetKernelCtx(),
-		modHttp: mod_http.NewModHttp(),
+		kCtx:       kern.GetKernelCtx(),
+		engineHttp: engine_http.NewEngineHttp(),
 	}
 	return sf
 }

+ 4 - 4
pkg/elems/canvas/canvas.go

@@ -10,8 +10,8 @@ import (
 
 // Canvas -- объект холста
 type Canvas struct {
-	size    types.ISize
-	pos     types.ICoord
+	size    types.IViewSize
+	pos     types.IViewCoord
 	diaMode string
 }
 
@@ -20,7 +20,7 @@ var (
 )
 
 // NewCanvas -- возвращает новый холст
-func NewCanvas(diaMode string, size types.ISize, pos types.ICoord) *Canvas {
+func NewCanvas(diaMode string, size types.IViewSize, pos types.IViewCoord) *Canvas {
 	hassert(diaMode != "", "NewCanvas(): diaMode is empty")
 	hassert(size != nil, "NewCanvas(): size is nil")
 	hassert(pos != nil, "NewCanvas(): pos is nil")
@@ -44,6 +44,6 @@ func (sf *Canvas) Draw(canvas *svg.SVG) {
 // Size -- возвращает размер холста
 //
 //go:fix inline
-func (sf *Canvas) Size()types.ISize {
+func (sf *Canvas) Size()types.IViewSize {
 	return sf.size
 }

+ 9 - 13
pkg/views/view_actor/view_actor.go

@@ -7,14 +7,12 @@ import (
 	svg "github.com/ajstarks/svgo"
 	"gitp78su.ipnodns.ru/svi/kern/v3"
 
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
-	"gitp78su.ipnodns.ru/svi/goarch/lev1/elem_actor"
 )
 
 // ViewActor -- SVG-фигура актора
 type ViewActor struct {
-	Actor_ *elem_actor.Actor
+	types.IElemActor
 }
 
 var (
@@ -22,20 +20,18 @@ var (
 )
 
 // NewViewActor -- возвращает новый SVG-актор
-func NewViewActor(actor *elem_actor.Actor, elem map[string]interface{}) *ViewActor {
+func NewViewActor(actor types.IElemActor) *ViewActor {
 	hassert(actor != nil, "in NewViewActor(), actor is nil")
 	sf := &ViewActor{
-		Actor_: actor,
+		IElemActor: actor,
 	}
 	return sf
 }
 
 // Draw -- рисует фигуру актора
-func (sf *ViewActor) Draw(canvas *svg.SVG, mapElem map[alias.Id]types.IDrawer) {
-	x := int(sf.Actor_.Label_.Coord_.X_)
-	y := int(sf.Actor_.Label_.Coord_.Y_)
-	offX := int(sf.Actor_.Label_.Offset_.X_)
-	offY := int(sf.Actor_.Label_.Offset_.Y_)
+func (sf *ViewActor) Draw(canvas *svg.SVG) {
+	x, y := sf.Coord().Int()
+	offX, offY := sf.Offset().Int()
 	// Голова
 	canvas.Circle(x, y, 10, "fill:none;stroke:red")
 	// Туловище
@@ -48,11 +44,11 @@ func (sf *ViewActor) Draw(canvas *svg.SVG, mapElem map[alias.Id]types.IDrawer) {
 	canvas.Line(x, y+40, x+10, y+55, "stroke:red;stroke-width:1")
 	// Надпись
 	log.Printf("ViewActor.Draw(): x=%d, y=%d, offX=%d, offY=%d", x, y, offX, offY)
-	canvas.Text(x+offX, y+offY, string(sf.Actor_.Label_.Get()), "font-size: 14px; font-family: sans-serif; fill: black")
-	if msgErr := sf.Check(mapElem); msgErr != "" { // Проверки на ошибки
+	canvas.Text(x+offX, y+offY, sf.String(), "font-size: 14px; font-family: sans-serif; fill: black")
+	if msgErr := sf.Check(); msgErr != "" { // Проверки на ошибки
 		canvas.Group("Ошибка")
 		canvas.Title(msgErr)
 		canvas.Image(x+offX-20, y+offY-20, 16, 16, "/static/img/warning.png")
-		canvas.Gend()
 	}
+	canvas.Gend()
 }

+ 2 - 2
pkg/views/view_use_group/view_use_group.go

@@ -11,7 +11,7 @@ import (
 // ViewUseGroup -- отображение группы вариантов использования
 type ViewUseGroup struct {
 	types.IElemUseGroup
-	Label_ types.IElemLabel
+	Label_ types.IViewLabel
 }
 
 var (
@@ -19,7 +19,7 @@ var (
 )
 
 // NewViewUseGroup -- возвращает новое отображение группы вариант использования
-func NewViewUseGroup(useGroup types.IElemUseGroup, label types.IElemLabel) types.IDrawer {
+func NewViewUseGroup(useGroup types.IElemUseGroup, label types.IViewLabel) types.IDrawer {
 	hassert(useGroup != nil, "NewViewUseGroup(): useGroup == nil")
 	sf := &ViewUseGroup{
 		IElemUseGroup: useGroup,