Mercurial > projects > mde
comparison mde/content/ServiceContent.d @ 173:a1ba9157510e
Enabled ServiceContentList to call its callbacks when its value changes. Tried to fix some other bugs, but this is not a very clean commit, due to wanting to make some big changes to enable better use of invariants next.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Sat, 08 Aug 2009 15:53:10 +0200 |
parents | 7f7b2011b759 |
children | 1f9d00f392bd |
comparison
equal
deleted
inserted
replaced
172:0dd49f333189 | 173:a1ba9157510e |
---|---|
23 */ | 23 */ |
24 module mde.content.ServiceContent; | 24 module mde.content.ServiceContent; |
25 | 25 |
26 import mde.content.AStringContent; | 26 import mde.content.AStringContent; |
27 | 27 |
28 debug { | |
29 import tango.util.log.Log : Log, Logger; | |
30 private Logger logger; | |
31 static this () { | |
32 logger = Log.getLogger ("mde.gui.content.ServiceContent"); | |
33 } | |
34 } | |
35 | |
28 /** Interface for ServiceContent and ServiceContentList. */ | 36 /** Interface for ServiceContent and ServiceContentList. */ |
29 interface IServiceContent : IContent { | 37 interface IServiceContent : IContent { |
30 void setContent (Content cont); | 38 void setContent (Content cont); |
31 } | 39 } |
32 | 40 |
44 | 52 |
45 /** Pass the content this service should prepare for. | 53 /** Pass the content this service should prepare for. |
46 * | 54 * |
47 * Stores the reference, because it won't be passed later. */ | 55 * Stores the reference, because it won't be passed later. */ |
48 override void setContent (Content cont) { | 56 override void setContent (Content cont) { |
57 T oCont = activeCont; | |
49 activeCont = cast(T)cont; | 58 activeCont = cast(T)cont; |
59 if ((oCont !is null) != (activeCont !is null)) | |
60 endEvent; | |
50 } | 61 } |
51 | 62 |
52 override bool opCall () { | 63 override bool opCall () { |
53 return activeCont is null; | 64 debug logger.trace ("ServiceContent.opCall: {}", symbol); |
65 return activeCont !is null; | |
54 } | 66 } |
55 // Doesn't support directly setting the value | 67 // Doesn't support directly setting the value |
56 override void opAssign (bool val) {} | 68 override void opAssign (bool val) {} |
57 | 69 |
58 package: | 70 package: |
70 super (symbol); | 82 super (symbol); |
71 } | 83 } |
72 | 84 |
73 void setContent (Content cont) { | 85 void setContent (Content cont) { |
74 foreach (child; list_) { | 86 foreach (child; list_) { |
75 debug assert (cast(IServiceContent)child !is null); | |
76 (cast(IServiceContent)child).setContent (cont); | 87 (cast(IServiceContent)child).setContent (cont); |
77 } | 88 } |
78 } | 89 } |
79 | 90 |
91 override void append (Content x) { | |
92 assert (cast(IBoolContent) x, "Only IBoolContent children are allowed!"); | |
93 list_ ~= x; | |
94 x.addCallback (&childChangeCB); | |
95 } | |
96 | |
80 override bool opCall () { | 97 override bool opCall () { |
81 foreach (child; list_) { | 98 debug logger.trace ("ServiceContentList.opCall"); |
82 debug assert (cast(IBoolContent)child !is null); | 99 return v; |
83 if (!(cast(IBoolContent)child)()) | |
84 return false; | |
85 } | |
86 return true; | |
87 } | 100 } |
88 // Doesn't support directly setting the value | 101 // Doesn't support directly setting the value |
89 override void opAssign (bool val) {} | 102 override void opAssign (bool val) {} |
90 | 103 |
91 | 104 |
99 static ServiceContentList createItems (char[] name) { | 112 static ServiceContentList createItems (char[] name) { |
100 char[] lName = "menus.services."~name; | 113 char[] lName = "menus.services."~name; |
101 auto ret = new ServiceContentList (lName); | 114 auto ret = new ServiceContentList (lName); |
102 | 115 |
103 // Many use callbacks on a generic class type. For this, we should be sure of the type. | 116 // Many use callbacks on a generic class type. For this, we should be sure of the type. |
104 (new AStringService(lName~".copy")).addCallback ((IContent c) { | 117 (new AStringService(lName~".copy")).addCallback (delegate void(IContent c) { |
105 debug assert (cast(AStringService)c); | 118 debug assert (cast(AStringService)c); |
106 with (cast(AStringService)c) { | 119 with (cast(AStringService)c) { |
107 if (activeCont !is null) | 120 if (activeCont !is null) |
108 clipboard = activeCont.toString(0); | 121 clipboard = activeCont.toString(0); |
109 } | 122 } |
110 }); | 123 }); |
111 (new AStringService(lName~".paste")).addCallback ((IContent c) { | 124 (new AStringService(lName~".paste")).addCallback (delegate void(IContent c) { |
112 debug assert (cast(AStringService)c); | 125 debug assert (cast(AStringService)c); |
113 with (cast(AStringService)c) { | 126 with (cast(AStringService)c) { |
114 if (activeCont !is null) | 127 if (activeCont !is null) |
115 activeCont = clipboard; | 128 activeCont = clipboard; |
116 } | 129 } |
117 }); | 130 }); |
118 | 131 |
119 new ServiceContentList(lName~".calculator"); | 132 new ServiceContentList(lName~".calculator"); |
120 (new IntService(lName~".calculator.increment")).addCallback ((IContent c) { | 133 (new IntService(lName~".calculator.increment")).addCallback (delegate void(IContent c) { |
121 debug assert (cast(IntService)c); | 134 debug assert (cast(IntService)c); |
122 with (cast(IntService)c) { | 135 with (cast(IntService)c) { |
123 if (activeCont !is null) | 136 if (activeCont !is null) |
124 activeCont = activeCont()+1; | 137 activeCont = activeCont()+1; |
125 } | 138 } |
126 }); | 139 }); |
127 (new IntService(lName~".calculator.decrement")).addCallback ((IContent c) { | 140 (new IntService(lName~".calculator.decrement")).addCallback (delegate void(IContent c) { |
128 debug assert (cast(IntService)c); | 141 debug assert (cast(IntService)c); |
129 with (cast(IntService)c) { | 142 with (cast(IntService)c) { |
130 if (activeCont !is null) | 143 if (activeCont !is null) |
131 activeCont = activeCont()-1; | 144 activeCont = activeCont()-1; |
132 } | 145 } |
133 }); | 146 }); |
134 return ret; | 147 return ret; |
135 } | 148 } |
136 | 149 |
137 private: | 150 private: |
151 void childChangeCB (IContent icont) { | |
152 if (v == false) { // then value changes iff icont() | |
153 debug assert (cast(IBoolContent) icont); | |
154 if ((cast(IBoolContent) icont)()) { | |
155 v = true; | |
156 endEvent; | |
157 } | |
158 } else { // we must check all children | |
159 v = false; | |
160 foreach (child; list_) { | |
161 if ((cast(IBoolContent)child)()) { | |
162 v = true; | |
163 break; | |
164 } | |
165 } | |
166 if (!v) | |
167 endEvent; | |
168 } | |
169 } | |
170 | |
171 bool v = false; // cache value so we can see when it changes | |
138 static char[] clipboard; | 172 static char[] clipboard; |
139 //TODO: lock on clipboard: static Mutex mutex; | 173 //TODO: lock on clipboard: static Mutex mutex; |
140 } | 174 } |