Page 1 of 2

Controls linkage

Posted: Sun Dec 25, 2016 7:37 pm
by DGDanforth
Linkage to a variable does not seem to work if the variable is deeply nested.
For example:
task.x works but
scheduler.tasks.task.x does not

task*: Task;
scheduler*: Scheduler;

Task* = RECORD x*: INTEGER END;
Scheduler* = RECORD tasks*: Tasks END;
Tasks* = POINTER TO RECORD task*: Task; next: Tasks END;

The BB documentation does not make that clear.
Unlike other views, these BlackBox controls can be linked to a program variable, or more exactly: to any field accessible through a globally declared variable. When the control is opened, BlackBox tries to link the control to its variable, using the advanced metaprogramming capabilities of the BlackBox Meta module. In this way, the link between control and variable can be built up automatically when a dialog is newly created or loaded from a file, and correct linking (i.e., correct typing) can be guaranteed even after a dialog layout had been edited or otherwise manipulated.
I think the key word is "tries". It seems it is not able in the above example even though the globally exported field "x" is accessible.
-Doug

Re: Controls linkage

Posted: Tue Dec 27, 2016 9:43 am
by Josef Templ
This is caused by the pointer inside the designator.
My understanding is that the Update mechanism requires
a single contiguous address range for checking if a control
needs to be updated. This would be hard to extend, I think.
An error message would be appropriate, but where and when
would it be shown?
It would be easiest to clarify this in the docu
(provided that my understanding is right).

- Josef

Re: Controls linkage

Posted: Tue Dec 27, 2016 7:40 pm
by DGDanforth
Josef, yes, however linkage also does not work for arrays of records
Tasks* = ARRAY 5 OF Task;
Task* = RECORD x*: INTEGER END;
tasks*: Tasks;
which*: INTEGER;

"link to" tasks[which].x
does not work even though all quantities are accessible.
-Doug

Re: Controls linkage

Posted: Wed Dec 28, 2016 7:18 am
by Josef Templ
Doug, I have tested your original example and it seems to works as expected.
You probably missed the ^ for explicit pointer dereferencing, e.g.
Test.scheduler.tasks^.task.x

The details can be seen in Controls.LookupPath.

- Josef

Re: Controls linkage

Posted: Wed Dec 28, 2016 7:36 pm
by DGDanforth
Josef Templ wrote:Doug, I have tested your original example and it seems to works as expected.
You probably missed the ^ for explicit pointer dereferencing, e.g.
Test.scheduler.tasks^.task.x

The details can be seen in Controls.LookupPath.

- Josef
Josef,
That's wonderful!
I'll now try that out and say if it works for me.
That will save a lot of unnecessary record copying.
-Doug

Re: Controls linkage

Posted: Wed Dec 28, 2016 9:14 pm
by DGDanforth
Josef,
That still does not work for me.
Here is a test program of simple form that does not work.
The link field in the form I use is "TestForms.focus^.x"
BB build #741

Code: Select all

MODULE TestForms;

	IMPORT
		Dialog,
		ObxRandom;
				
	TYPE
		List* =	POINTER TO RECORD
				x*:	REAL;
				next:	List
			END;
			
	VAR
		list:	List;
		focus*:	List;
		x*:	REAL;

	PROCEDURE First*;
	BEGIN
		focus := list;
		IF focus # NIL THEN 
			Dialog.UpdateReal(focus.x); 
			x := focus.x; Dialog.UpdateReal(x)
		END
	END First;
	
	PROCEDURE Next*;
	BEGIN
		IF focus # NIL THEN 
			focus := focus.next; 
			IF focus # NIL THEN 
				Dialog.UpdateReal(focus.x); 
				x := focus.x; Dialog.UpdateReal(x)
			END
		END
	END Next;
	
	PROCEDURE Do*;
	VAR t: List; n, N: INTEGER;
	BEGIN
		N := 5;
		list := NIL;
		FOR n := 0 TO N-1 DO
			NEW(t);
			t.x := ObxRandom.Uniform();
			t.next := list; list := t;
		END;
		focus := list;
		Dialog.UpdateReal(focus.x);
		x := focus.x; Dialog.UpdateReal(x)
	END Do;
	
END TestForms.

 TestForms.Do
 "StdCmds.OpenDoc('Test/Rsrc/Forms')"

Re: Controls linkage

Posted: Thu Dec 29, 2016 12:51 am
by DGDanforth
I am getting some very strange behavior.
When first loaded and "Do" is pressed the focus^.x field is not displayed.
If I activate Next. It is still not displayed.
But if I close the form and then reopen it I do see the value of focus^x.
The value is equal to that previously displayed via "x" only. However,
pressing "Next" does not change the focus^.x value "in the form" but it
must be changing the focus because the x value changes.

So it appears that there is some form dependent problem blocking the Update(focus.x) display.

-Doug

Re: Controls linkage

Posted: Thu Dec 29, 2016 12:53 am
by DGDanforth
Here is an updated version of the code I am testing

Code: Select all

MODULE TestForms;

	IMPORT
		Dialog,
		ObxRandom;
				
	TYPE
		List* =	POINTER TO RECORD
				x*:	REAL;
				next:	List
			END;
			
	VAR
		list:	List;
		focus*:	List;
		x*:	REAL;

	PROCEDURE Update;
	BEGIN
		IF focus # NIL THEN
				x := focus.x; 
				Dialog.UpdateReal(x);
				Dialog.UpdateReal(focus.x)
		END
	END Update;
	
	PROCEDURE Do*;
	VAR t: List; n, N: INTEGER;
	BEGIN
		N := 5;
		list := NIL;
		FOR n := 0 TO N-1 DO
			NEW(t);
			t.x := ObxRandom.Uniform();
			t.next := list; list := t;
		END;
		focus := list;
		Update
	END Do;
	
	PROCEDURE First*;
	BEGIN
		focus := list;
		Update
	END First;
	
	PROCEDURE Next*;
	BEGIN
		IF focus # NIL THEN 
			focus := focus.next; 
			Update
		END
	END Next;
	
END TestForms.

 TestForms.Do
 "StdCmds.OpenDoc('Test/Rsrc/Forms')"

Re: Controls linkage

Posted: Thu Dec 29, 2016 1:06 am
by DGDanforth
TestForms.jpg

Re: Controls linkage

Posted: Thu Dec 29, 2016 6:50 am
by Josef Templ
If the dereferenced pointer is changed, this means that the
control must re-evaluate its link, which it is not doing.
This may be subject to improvement. I don't know how complicated it is, though.

In order to force a re-evaluation of all links you can call "Controls.Relink".

- Josef