|
|
@@ -1,197 +0,0 @@
|
|
|
-// package use_link -- связь между объектами
|
|
|
-package use_link
|
|
|
-
|
|
|
-import (
|
|
|
- "fmt"
|
|
|
-
|
|
|
- "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
|
|
|
- "gitp78su.ipnodns.ru/svi/goarch/lev0/cons"
|
|
|
- "gitp78su.ipnodns.ru/svi/goarch/lev0/types"
|
|
|
- "gitp78su.ipnodns.ru/svi/goarch/lev1/coord"
|
|
|
- "gitp78su.ipnodns.ru/svi/goarch/pkg/elems/elem_base"
|
|
|
- "gitp78su.ipnodns.ru/svi/kern/v3"
|
|
|
-)
|
|
|
-
|
|
|
-// UseLink -- связь между объектами
|
|
|
-type UseLink struct {
|
|
|
- ElemBase_ *elem_base.ElemBase `yaml:"elem_base"`
|
|
|
- CoordEnd_ *coord.Coord `yaml:"coord1"` // Координаты второй точки
|
|
|
- Src_ alias.Id `yaml:"src"` // Источник координат
|
|
|
- Dst_ alias.Id `yaml:"dst"` // Получатель координат
|
|
|
-
|
|
|
- TypeLink_ string `yaml:"typeLink"` // Тип связи
|
|
|
-}
|
|
|
-
|
|
|
-var (
|
|
|
- hassert = kern.GetFnHassert()
|
|
|
-)
|
|
|
-
|
|
|
-// NewUseLink -- возвращает новую связь
|
|
|
-func NewUseLink(elemBase *elem_base.ElemBase, coordEnd *coord.Coord) *UseLink {
|
|
|
- hassert(elemBase != nil, "NewUseLink(): elemBase is nil")
|
|
|
- hassert(coordEnd != nil, "NewUseLink(): coordEnd is nil")
|
|
|
-
|
|
|
- id := elemBase.Id_
|
|
|
- _src := elemBase.Elem_["src"]
|
|
|
- src0, isOk := _src.(string)
|
|
|
- hassert(isOk, "NewUseLink(): id=%q, field `src` not string, type=%T, value=%v", id, _src, elemBase.StrElem_)
|
|
|
- src := alias.Id(src0)
|
|
|
- hassert(src != "", "NewUseLink(): id=%q, `src` is empty", id)
|
|
|
- _dst := elemBase.Elem_["dst"]
|
|
|
- dst0, isOk := _dst.(string)
|
|
|
- hassert(isOk, "NewUseLink(): id=%q, field `dst` not string, type=%T, value=%+v<br>%+v", id, _dst, _dst, elemBase.StrElem_)
|
|
|
- dst := alias.Id(dst0)
|
|
|
- _typeLink, isOk := elemBase.Elem_["type_link"]
|
|
|
- hassert(isOk, "NewUseLink(): name=%q, field `type_link` not found<br>%+v", id, elemBase.StrElem_)
|
|
|
- typeLink, isOk := _typeLink.(string)
|
|
|
- hassert(isOk, "NewUseLink(): name=%q, `type_link`(%+v) not string", id, _typeLink)
|
|
|
- hassert(typeLink != "", "NewUseLink(): name=%q, type_link=%q is empty", id, typeLink)
|
|
|
- sf := &UseLink{
|
|
|
- ElemBase_: elemBase,
|
|
|
- CoordEnd_: coordEnd,
|
|
|
- Src_: src,
|
|
|
- Dst_: dst,
|
|
|
- TypeLink_: typeLink,
|
|
|
- }
|
|
|
- return sf
|
|
|
-}
|
|
|
-
|
|
|
-// Links -- ссылки актора
|
|
|
-func (sf *UseLink) Links() []alias.Id {
|
|
|
- return []alias.Id{sf.Src_, sf.Dst_}
|
|
|
-}
|
|
|
-
|
|
|
-// Check -- проверяет связи между объектами
|
|
|
-func (sf *UseLink) Check(mapDrawer map[alias.Id]types.IDrawer) string {
|
|
|
- if sf.Dst_ == sf.Src_ {
|
|
|
- return fmt.Sprintf("ВНИМАНИЕ! Источник и получатель совпадают\nsrc=%v, dst=%v\n", sf.Src_, sf.Dst_)
|
|
|
- }
|
|
|
- if msgErr := sf.checkSrc(mapDrawer); msgErr != "" {
|
|
|
- return "ОШИБКА при проверке связи источника\n" + msgErr
|
|
|
- }
|
|
|
- if msgErr := sf.checkDst(mapDrawer); msgErr != "" {
|
|
|
- return "ОШИБКА при проверке связи получателя\n" + msgErr
|
|
|
- }
|
|
|
- if sf.TypeLink_ == "" { // Проверка на правильность типа связи
|
|
|
- return "Пустой собственный тип связи\n"
|
|
|
- }
|
|
|
- return ""
|
|
|
-}
|
|
|
-
|
|
|
-// проверить связь получателя
|
|
|
-func (sf *UseLink) checkDst(mapDrawer map[alias.Id]types.IDrawer) string {
|
|
|
- if sf.Dst_ == "" {
|
|
|
- return "ОШИБКА получатель `dst` не задан"
|
|
|
- }
|
|
|
- dst, isOk := mapDrawer[sf.Dst_] // Вычислить, если такой получатель
|
|
|
- if !isOk {
|
|
|
- return "Отсутствует собственный получатель(dst)\n"
|
|
|
- }
|
|
|
- // Вычислить на допустимые типы для получателя
|
|
|
- switch dst.Type() {
|
|
|
- case cons.TypeUseActor:
|
|
|
- actor, isOk := dst.(types.IActor)
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("Недопустимый тип получателя(%q)\nтип=%q\n", dst.Id(), dst.Type())
|
|
|
- }
|
|
|
- isOk = false
|
|
|
- for _, id := range actor.Links() {
|
|
|
- if id == sf.ElemBase_.Id_ {
|
|
|
- isOk = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("Невзаимная ссылка\nid=%q,dst=(%q)", sf.ElemBase_.Id_, actor.Id())
|
|
|
- }
|
|
|
- case cons.TypeUseLink:
|
|
|
- link, isOk := dst.(types.IElemLinker)
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("Недопустимый тип получателя(%q)\nтип=%q\n", dst.Id(), dst.Type())
|
|
|
- }
|
|
|
- isOk = sf.ElemBase_.Id_ == link.DstId() || sf.ElemBase_.Id_ == link.SrcId()
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.ElemBase_.Id_, link.Id())
|
|
|
- }
|
|
|
- case cons.TypeUseCase:
|
|
|
- useCase, isOk := dst.(types.IElemUseCase)
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("id=%q, Недопустимый тип получателя(%q)\nтип=%q\n", sf.ElemBase_.Id_, dst.Id(), dst.Type())
|
|
|
- }
|
|
|
- isOk = false
|
|
|
- for _, id := range useCase.Links() {
|
|
|
- if id == sf.ElemBase_.Id_ {
|
|
|
- isOk = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.ElemBase_.Id_, useCase.Id())
|
|
|
- }
|
|
|
- default: // Недопустимый источник
|
|
|
- return fmt.Sprintf("id=%q, Недопустимый тип получателя(%q)\nid=%q\n", sf.ElemBase_.Id_, dst.Type(), dst.Id())
|
|
|
- }
|
|
|
- return ""
|
|
|
-}
|
|
|
-
|
|
|
-// Проверяет связь источника
|
|
|
-func (sf *UseLink) checkSrc(mapDrawer map[alias.Id]types.IDrawer) string {
|
|
|
- if sf.Src_ == "" {
|
|
|
- return "ВНИМАНИЕ! Источник связи не задан(src)\n"
|
|
|
- }
|
|
|
- src, isOk := mapDrawer[sf.Src_]
|
|
|
- if !isOk {
|
|
|
- return "Отсутствует источник(src)\n"
|
|
|
- }
|
|
|
- switch src.Type() {
|
|
|
- case cons.TypeUseActor:
|
|
|
- isOk = false
|
|
|
- actor := types.IActor(src)
|
|
|
- for _, id := range actor.Links() { // Проверка на взаимность
|
|
|
- if id == sf.ElemBase_.Id_ {
|
|
|
- isOk = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("Невзаимная ссылка с актором %q\n", actor.Id())
|
|
|
- }
|
|
|
- case cons.TypeUseLink:
|
|
|
- link, isOk := src.(types.IElemLinker)
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("Несоответствие типа источника(%q)\nтип='useLink'\n", src.Id())
|
|
|
- }
|
|
|
- isOk = sf.ElemBase_.Id_ == link.DstId() || sf.ElemBase_.Id_ == link.SrcId()
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.ElemBase_.Id_, link.Id())
|
|
|
- }
|
|
|
- case cons.TypeUseCase:
|
|
|
- useCase, isOk := src.(types.IElemUseCase)
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("id=%q, Тип источника(%q) не совпадает с фактическим\nтип='useCase'\n", sf.ElemBase_.Id_, src.Id())
|
|
|
- }
|
|
|
- isOk = false
|
|
|
- for _, id := range useCase.Links() { // Проверка на взаимность
|
|
|
- if id == sf.ElemBase_.Id_ {
|
|
|
- isOk = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if !isOk {
|
|
|
- return fmt.Sprintf("id=%q, Невзаимная ссылка(%q)\n", sf.ElemBase_.Id_, useCase.Id())
|
|
|
- }
|
|
|
- default: // Неизвестный источник
|
|
|
- return fmt.Sprintf("id=%q, неизвестный тип источника(%q)<br>id=%q\n", sf.ElemBase_.Id_, src.Type(), src.Id())
|
|
|
- }
|
|
|
- return ""
|
|
|
-}
|
|
|
-
|
|
|
-// SrcId -- возвращает источник связи
|
|
|
-func (sf *UseLink) SrcId() alias.Id {
|
|
|
- return sf.Src_
|
|
|
-}
|
|
|
-
|
|
|
-// DstId -- возвращает получателя связи
|
|
|
-func (sf *UseLink) DstId() alias.Id {
|
|
|
- return sf.Dst_
|
|
|
-}
|