Controls linkage

User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Controls linkage

Post 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
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Controls linkage

Post 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
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Controls linkage

Post 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
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Controls linkage

Post 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
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Controls linkage

Post 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
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Controls linkage

Post 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')"
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Controls linkage

Post 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
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Controls linkage

Post 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')"
User avatar
DGDanforth
Posts: 1061
Joined: Tue Sep 17, 2013 1:16 am
Location: Palo Alto, California, USA
Contact:

Re: Controls linkage

Post by DGDanforth »

TestForms.jpg
User avatar
Josef Templ
Posts: 2047
Joined: Tue Sep 17, 2013 6:50 am

Re: Controls linkage

Post 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
Post Reply