treebinding.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package binding
  2. // DataTreeRootID const is the value used as ID for the root of any tree binding.
  3. const DataTreeRootID = ""
  4. // DataTree is the base interface for all bindable data trees.
  5. //
  6. // Since: 2.4
  7. type DataTree interface {
  8. DataItem
  9. GetItem(id string) (DataItem, error)
  10. ChildIDs(string) []string
  11. }
  12. type treeBase struct {
  13. base
  14. ids map[string][]string
  15. items map[string]DataItem
  16. }
  17. // GetItem returns the DataItem at the specified id.
  18. func (t *treeBase) GetItem(id string) (DataItem, error) {
  19. t.lock.RLock()
  20. defer t.lock.RUnlock()
  21. if item, ok := t.items[id]; ok {
  22. return item, nil
  23. }
  24. return nil, errOutOfBounds
  25. }
  26. // ChildIDs returns the ordered IDs of items in this data tree that are children of the specified ID.
  27. func (t *treeBase) ChildIDs(id string) []string {
  28. t.lock.RLock()
  29. defer t.lock.RUnlock()
  30. if ids, ok := t.ids[id]; ok {
  31. return ids
  32. }
  33. return []string{}
  34. }
  35. func (t *treeBase) appendItem(i DataItem, id, parent string) {
  36. t.items[id] = i
  37. ids, ok := t.ids[parent]
  38. if !ok {
  39. ids = make([]string, 0)
  40. }
  41. for _, in := range ids {
  42. if in == id {
  43. return
  44. }
  45. }
  46. t.ids[parent] = append(ids, id)
  47. }
  48. func (t *treeBase) deleteItem(id, parent string) {
  49. delete(t.items, id)
  50. ids, ok := t.ids[parent]
  51. if !ok {
  52. return
  53. }
  54. off := -1
  55. for i, id2 := range ids {
  56. if id2 == id {
  57. off = i
  58. break
  59. }
  60. }
  61. if off == -1 {
  62. return
  63. }
  64. t.ids[parent] = append(ids[:off], ids[off+1:]...)
  65. }
  66. func parentIDFor(id string, ids map[string][]string) string {
  67. for parent, list := range ids {
  68. for _, child := range list {
  69. if child == id {
  70. return parent
  71. }
  72. }
  73. }
  74. return ""
  75. }