Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

405
LINES

< > BotCompany Repo | #1015892 // DynModule [base class for dynamic modules]

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (21700L/133K).

1  
please include function myInnerClasses.
2  
3  
static abstract class DynModule extends DynamicObject is Enterable, ChangeTriggerable
4  
ifdef DynModule_NewChangeEvent , IHasChangeListeners endifdef {
5  
  // we really shouldn't have used up these variable names
6  
  // (subclasses can't overload them due to how the persistence works)
7  
  S name, toolTip; // module name, module tool tip in task bar
8  
  
9  
  PersistableThrowable _error;
10  
  Map<S, Collection<S>> mechLists;
11  
  Map<S, Bool> _persistenceInfo;
12  
  
13  
  transient O _host; // pointer to this module's stem
14  
  
15  
  transient Map<O, IVF1> timers = newWeakHashMap(); // all kinds of resources actually; value is closer helper
16  
  transient Set<AutoCloseable> _resources = synchroHashSet();
17  
  transient Lock lock; // set by stem
18  
  transient bool persistOnChangedField = true;
19  
  transient int changeCount;
20  
  transient new O changeCountSync;
21  
  transient L onChange;
22  
  transient L onTransientChange;
23  
  transient bool verboseTimers;
24  
  transient ReliableSingleThread rstUpdate;
25  
  transient Set<S> componentFieldsToKeep;
26  
  
27  
  // TODO: use DynamicObject for this
28  
  transient MapSO transientGeneralMap = synchroHashMap();
29  
  
30  
  transient Q q; // module command queue
31  
  transient L onFieldChange; // also for non-persistent fields. L<voidfunc(S field)>
32  
  transient bool _hasPreviousBounds;
33  
  transient new StringBuffer _printLog;
34  
  transient bool deleted;
35  
  
36  
  *() {
37  
    if (useErrorHandling())
38  
      dm_initErrorHandling();
39  
      
40  
    // TODO: DynModule is now shared between modules, so not good
41  
    setMainDesktopPane((JDesktopPane) getCreatorOpt('desktop));
42  
  }
43  
  
44  
  bool useErrorHandling() { true; }
45  
  
46  
  bool isVisible() { ret isTrue(getOpt(_host, 'visible)); }
47  
  
48  
  S moduleName() { ret name; }
49  
  
50  
  void setModuleName(S name) {
51  
    S oldName = this.name;
52  
    if (!eq(name, oldName)) {
53  
      setField(+name);
54  
      possiblyInternalFrameTitle(vis(), name);
55  
      vmBus_send('moduleNameChange, this, oldName, name);
56  
    }
57  
  }
58  
  
59  
  void setModuleToolTip(S toolTip) {
60  
    this.toolTip = toolTip;
61  
  }
62  
  
63  
  JComponent vis() {
64  
    ret (JComponent) getOpt(_host, 'vis);
65  
  }
66  
  
67  
  <A extends AutoCloseable> A ownResource(A a) {
68  
    if (a != null)
69  
      _resources.add(a);
70  
    ret a;
71  
  }
72  
  
73  
  <A> A ownTimer(A timer) {
74  
    if (timer cast AutoCloseable)
75  
      ownResource(timer);
76  
    else
77  
      ownTimer(timer, lambda1 cancelTimerOrInterruptThread);
78  
    ret timer;
79  
  }
80  
  
81  
  void ownTimer(O timer, IVF1 closerHelper) {
82  
    timers.put(timer, closerHelper);
83  
  }
84  
  
85  
  void singleTimer(java.util.Timer timer) {
86  
    stopAllTimers();
87  
    ownTimer(timer);
88  
  }
89  
  
90  
  void stopAllTimers() {
91  
    for (AutoCloseable resource : getAndClearList(_resources)) {
92  
      if (verboseTimers)
93  
        print("Releasing resource: " + resource);
94  
      pcall { resource.close(); }
95  
    }
96  
      
97  
    for (O timer, IVF1 closerHelper : getAndClearMap(timers)) {
98  
      if (verboseTimers)
99  
        print("Stopping timer: " + closerHelper + " / " + timer);
100  
      pcallF(closerHelper, timer);
101  
    }
102  
  }
103  
  
104  
  bool isDeleted() { ret deleted; }
105  
  bool deleted() { ret deleted; }
106  
  
107  
  void cleanMeUp_dynModule {
108  
    set deleted;
109  
    dispose q;
110  
    stopAllTimers();
111  
  }
112  
  
113  
  void persistMe {
114  
    synchronized(changeCountSync) { ++changeCount; }
115  
    pcallFAll(onChange); callOpt(_host, '_change);
116  
    updateMe();
117  
  }
118  
  
119  
  void fireChangeWithoutPersisting {
120  
    pcallFAll(onChange);
121  
  }
122  
  
123  
  void fireTransientChange {
124  
    pcallFAll(onTransientChange);
125  
  }
126  
  
127  
  final void _change { persistMe(); }
128  
  final public void change { persistMe(); }
129  
  
130  
  void updateMe {
131  
    rstUpdate().trigger();
132  
  }
133  
  
134  
  void changeAndUpdate { _change(); updateMe(); }
135  
  
136  
  bool setField_noPersist(S name, O value) {
137  
    ret setField(name, value, true);
138  
  }
139  
  
140  
  bool _setField(S name, O value) {
141  
    ret setField(name, value);
142  
  }
143  
  
144  
  bool setField(S name, O value, bool noPersist default false) {
145  
    temp enter();
146  
    pcall { // some really weird classes fail on equals() (BCEL JavaClass, I'm looking at you)
147  
      if (eq(get(this, name), value)) false;
148  
    }
149  
    ret setField_noCheck(name, value, noPersist);
150  
  }
151  
    
152  
  // always set even if equal
153  
  bool setField_noCheck(S name, O value, bool noPersist default false) enter {
154  
    //set(this, name, value); 
155  
    setOpt(this, name, value); // XXX allow virtual fields
156  
    pcallFAll(onFieldChange, name);
157  
    
158  
    // XXX - new check for transient field
159  
    if (!noPersist && dm_isPersistentField(me(), name))
160  
      _change();
161  
    true;
162  
  }
163  
  
164  
  <A> A setFieldAndReturn(S name, A value) {
165  
    setField(name, value);
166  
    ret value;
167  
  }
168  
  
169  
  bool setFields(O... params) {
170  
    bool change = false;
171  
    for (int i = 0; i < l(params); i += 2)
172  
      if (setField((S) params[i], params[i+1])) change = true;
173  
    ret change;
174  
  }
175  
  
176  
  void start {
177  
    _hasPreviousBounds = dm_getBounds() != null;
178  
    if (hasMethod_onTypes(this, 'onTopInput, S))
179  
      dm_onTopInput_q(voidfunc(S s) { call(module(), 'onTopInput, s) });
180  
  }
181  
  
182  
  void revisualize {
183  
    call(dm_os(), 'revisualizeModule, _host);
184  
  }
185  
  
186  
  bool useEnterShortcut() { false; }
187  
  
188  
  public AutoCloseable enter() {
189  
    AutoCloseable c = tempSetBetterThreadLocalIfNecessary_weakRef(dm_current_generic_tl(), this);
190  
    
191  
    /// XXX shortcut, testing now (doesn't seem to work yet)
192  
    if (c == null && useEnterShortcut()) null; // assume we are entered (so the rest of what we do in this function is also done)
193  
    
194  
    O realMC = getMainClass(this);
195  
    if (printToModule())
196  
      c = combineAutoCloseables(c, tempInterceptPrintIfNotIntercepted(_printToModuleInterceptor()));
197  
    if (realMC != mc()) {
198  
      if (printToModule())
199  
        c = combineAutoCloseables(c, (AutoCloseable) callOpt(realMC, 'tempInterceptPrintIfNotIntercepted, _printToModuleInterceptor()));
200  
      else
201  
        c = combineAutoCloseables(c, tempInterceptPrintIfNotIntercepted(func(S s) -> bool {
202  
          ret false with call(realMC, 'print, s);
203  
        }));
204  
      c = combineAutoCloseables(c, tempSetTL(realMC_tl(), realMC));
205  
    }
206  
    ret c;
207  
  }
208  
  
209  
  F1<S, Bool> _printToModuleInterceptor() {
210  
    ret func(S s) -> bool {
211  
      if (print_preprocess != null) s = (S) callF(print_preprocess, s);
212  
      s = fixNewLines(s);
213  
      Appendable loc = _printLog;
214  
      Appendable buf = print_log;
215  
      int loc_max = print_log_max;
216  
      if (buf != loc && buf != null) {
217  
        print_append(buf, s, print_log_max);
218  
        loc_max = local_log_max;
219  
      }
220  
      if (loc != null) 
221  
        print_append(loc, s, loc_max);
222  
      if (printAlsoToSystemOut)
223  
        System.out.print(s);
224  
      false;
225  
    };
226  
  }
227  
  
228  
  bool printToModule() { true; } // on by default now
229  
  
230  
  AutoCloseable enterAndLock() {
231  
    ret combineAutoCloseables(enter(), tempLock(lock));
232  
  }
233  
  
234  
  bool setError(Throwable e) {
235  
    setField(_error := persistableThrowable(e));
236  
    true;
237  
  }
238  
  
239  
  void clearError {
240  
    setField(_error := null);
241  
  }
242  
  
243  
  ifdef DynModule_NewChangeEvent
244  
    public selfType onChange(Runnable r) {
245  
      lock lock;
246  
      if (onChange == null) onChange = synchroList();
247  
      addIfNotThere(onChange, r);
248  
      this;
249  
    }
250  
    
251  
    public selfType removeChangeListener(Runnable r) {
252  
      remove(onChange, r);
253  
      this;
254  
    }
255  
  endifdef
256  
  
257  
  ifndef DynModule_NewChangeEvent
258  
    void onChange(Runnable r) {
259  
      lock lock;
260  
      if (onChange == null) onChange = synchroList();
261  
      addIfNotThere(onChange, r);
262  
    }
263  
  
264  
    public void removeChangeListener(Runnable r) {
265  
      remove(onChange, r);
266  
    }
267  
  endifndef
268  
  
269  
  void onFieldChange(VF1<S> r) {
270  
    lock lock;
271  
    if (onFieldChange == null) onFieldChange = synchroList();
272  
    addIfNotThere(onFieldChange, r);
273  
  }
274  
  
275  
  void removeFieldChangeListener(VF1<S> r) {
276  
    remove(onFieldChange, r);
277  
  }
278  
  
279  
  ifndef DynModule_NewChangeEvent
280  
    void onChangeAndNow(Runnable r) {
281  
      onChange(r);
282  
      callF(r);
283  
    }
284  
  endifndef
285  
  
286  
  // forward to main class
287  
  void onChangeAndNow(JComponent c, O r) {
288  
    onUpdateAndNow(c, r);
289  
  }
290  
  
291  
  void onChangeAndNow(L<? extends JComponent> l, O r) {
292  
    main onChangeAndNow(l, r);
293  
  }
294  
  
295  
  void onChangeAndNow(JTextComponent c, IVF1<S> r) {
296  
    onUpdateAndNow(c, r);
297  
  }
298  
  
299  
  /*static*/ <A extends JComponent> A onChange(A tc, O r) {
300  
    onUpdate(tc, r);
301  
    ret tc;
302  
  }
303  
304  
  void update() {}
305  
  
306  
  void unvisualize() {
307  
    zeroAllFieldsOfTypeExcept(this, Component, componentFieldsToKeep);
308  
  }
309  
  
310  
  // return L<AbstractAction> (legacy)
311  
  // or litobjectarray(text, Runnable, text, Runnable, ...)
312  
  O menuItems() {
313  
    null;
314  
  }
315  
  
316  
  void enhanceFrame(Container f) {
317  
    ifndef NoMenuItems
318  
    O items = menuItems();
319  
    if (items instanceof O[])
320  
      items = paramsToAbstractActions((O[]) items);
321  
    internalFramePopupMenuFromActions_threaded(f, (L) items);
322  
    endifndef
323  
    ifndef NoSwitchableFields
324  
    S switchableFields = cast callOpt(this, 'switchableFields);
325  
    Set<S> set = asLinkedHashSet(splitAtSpace(switchableFields));
326  
    new Matches m;
327  
    for (S field : allFields(getClass()))
328  
      if (startsWith(field, "_switchableField_", m))
329  
        set.add(m.rest());
330  
    for (S field : set) {
331  
      Class type = fieldType(this, field);
332  
      if (eq(bool.class, type))
333  
        dm_boolFieldMenuItem(f, field);
334  
      else if (eq(int.class, type))
335  
        dm_intFieldMenuItem(f, field);
336  
      else if (eq(long.class, type))
337  
        dm_longFieldMenuItem(f, field);
338  
      else if (eq(double.class, type))
339  
        dm_doubleFieldMenuItem(f, field);
340  
      else if (eq(float.class, type))
341  
        dm_floatFieldMenuItem(f, field);
342  
      else if (eq(S, type))
343  
        dm_stringFieldMenuItem(f, field);
344  
      else if (eq(File.class, type))
345  
        dm_fileFieldMenuItem(f, field);
346  
    }
347  
    endifndef
348  
  }
349  
  
350  
  // assume this is called in start(), so no locking
351  
  ReliableSingleThread rstUpdate() {
352  
    if (rstUpdate == null) rstUpdate = dm_rst(this, r enter { update(); });
353  
    ret rstUpdate;
354  
  }
355  
  
356  
  Q q() enter {
357  
    if (q == null) {
358  
      lock lock;
359  
      if (q == null) q = dm_startQ();
360  
    }
361  
    ret q;
362  
  }
363  
  
364  
  <A> A withUpdate(A a) {
365  
    rstUpdate().trigger();
366  
    ret a;
367  
  }
368  
  
369  
  DynModule module() { this; }
370  
  DynModule me() { this; }
371  
  
372  
  JComponent visualize() {
373  
    ret dm_noVisualisation();
374  
  }
375  
  
376  
  S programTitle_cache;
377  
  S programTitle() {
378  
    if (programTitle_cache == null)
379  
      programTitle_cache = snippetTitle(programID(mainClass(this)));
380  
    ret programTitle_cache;
381  
  }
382  
  
383  
  // field must be non-transient
384  
  void doPersist(S field) {
385  
    _persistenceInfo = mapMinus(_persistenceInfo, field);
386  
  }
387  
  
388  
  void dontPersist(S field) {
389  
    _persistenceInfo = mapPlus(_persistenceInfo, field := false);
390  
  }
391  
  
392  
  Appendable _actualPrintLog() { ret printToModule() ? _printLog : print_log; }
393  
  
394  
  O getHost() { ret _host; }
395  
  
396  
  !include #1031423 // DynModule convenience methods
397  
} // end of DynModule
398  
399  
static void _registerTimer(java.util.Timer timer) {
400  
  _registerTimer_original(timer);
401  
  var mod = dm_currentModule();
402  
  mod?.ownTimer(timer);
403  
}
404  
405  
!include once #1023504

download  show line numbers  debug dex  old transpilations   

Travelled to 21 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, jozkyjcghlvl, lnbujpyubztb, lpdgvwnxivlt, mowyntqkapby, mqqgnosmbjvj, onxytkatvevr, podlckwnjdmb, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, whxojlpjdney, xrpafgyirdlv

No comments. add comment

Snippet ID: #1015892
Snippet name: DynModule [base class for dynamic modules]
Eternal ID of this version: #1015892/209
Text MD5: c95ad31395a8a070f3a4e65f3ef67ccf
Transpilation MD5: 8972aaca8849675a75c5e8660f0cad59
Author: stefan
Category: javax / stefan's os
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-07-16 00:32:14
Source code size: 11278 bytes / 405 lines
Pitched / IR pitched: No / No
Views / Downloads: 1327 / 5428
Version history: 208 change(s)
Referenced in: [show references]