initiating position.location , how to combine into a single function?

in my program, the watch calls my onPosition function, and towards the start of the program I have it "initiate" points to be used.  Is it possible to compress this code into a single function, instead of having to repeat the calls three times? 

class ProgramView extends WatchUi.View {
    var pointA, pointB, pointC; 
	
    function initiatePoints (minfo) { 
		if ( (minfo != null) && (minfo.accuracy != null) ) { 
			var curpos = minfo.position.toDegrees();  
			
			if (pointA == null) {
				pointA = new Position.Location({ :latitude => curpos[0], :longitude => curpos[1], :format => :degrees });
			} else {
				pointA.initialize({ :latitude => curpos[0], :longitude => curpos[1], :format => :degrees });		
			}
			
			if (pointB == null) {
				pointB = new Position.Location({ :latitude => curpos[0], :longitude => curpos[1], :format => :degrees });
			} else {
				pointB.initialize({ :latitude => curpos[0], :longitude => curpos[1], :format => :degrees });		
			}
			
			if (pointC == null) {
				pointC = new Position.Location({ :latitude => curpos[0], :longitude => curpos[1], :format => :degrees });
			} else {
				pointC.initialize({ :latitude => curpos[0], :longitude => curpos[1], :format => :degrees });		
			}
			//...

 

I tried to create a smaller function like the below, however it isn't working as expected.  The point data is somehow erroneously duplicating, as if it is only defining/redefining a single object.  When I load the memory view in the simulator, when I go to print out the different pointA, PointB, PointC variables, they all end up referring to the same object, the same object number.  Thus, it appears as if my attempt to do this, was unsuccessful.  

// pardon this code has not been recently tested, I'm typing from memory

class ProgramView extends WatchUi.View {
    var pointA, pointB, pointC; 
	
	function initiatePoints (minfo) { 
		if ( (minfo != null) && (minfo.accuracy != null) ) {
			var curpos = minfo.position.toDegrees();  
			
			setPoint(pointA, curpos);
			setPoint(pointB, curpos);
			setPoint(pointC, curpos);
		//...
	}
	
	function setPoint(locationVar, posInDegrees)
		if (locationVar == null) {
			locationVar = new Position.Location({ :latitude => posInDegrees[0], :longitude => posInDegrees[1], :format => :degrees });
		} else {
			locationVar.initialize({ :latitude => posInDegrees[0], :longitude => posInDegrees[1], :format => :degrees });		
		}
	}

I think in order to stick the initiating code into a separate function, I have to use reference values or somehow specify that I am initiating separate variable objects, not the same object.  Can anyone give me some good clues on how to do this, so I can prevent unnecessary duplication of code?

(apologies: the second code segment I wrote from memory, because I had to remove that functionality because it didn't work.  I may have tried to use reference variables or somehow re-write the "setPoint" function so that it was better than how it appears here, however I was unable to make it work.)

  • When checking accuracy, you probably want to check for >=QUALITY_POOR as you may not have a valid position, and in your code, it seems you set pointA, pointB and pointC to the same thing.

    It's unclear to me what you are trying to do.

  • Oh wait.. when you include pointA, pointB, pointC as value, you are passing them by value, not by reference, so when you change them in setPoint you are change the value local to that function.

    in setPoint, add 

    return locationVar;

    at the end

    and when calling it

    do

    pointA=setPoint(pointA, curpos);

    for example.

  • Yes, I was initiating the points to be the same value in this function.  Later in the program I can set them to different things and use them in other ways.

    Yes, I was trying to pass by value, and I have read that one cannot pass by reference so easily in Monkey C.

    Using a return value will probably work.  I'll give it a try.  (thanks a lot for the advice)

    ...

    you are passing them by value, not by reference, so when you change them in setPoint you are change the value local to that function

    and when I tried to initialize these objects, instead of just changing them, unexpected errors resulted. 

  • the return will work.  But you may still want to look at the accuracy value.  I'm not sure what minfo is, and for a widget or device app, you need to enable GPS to get locations.  The sim is a bit odd when it comes to this 

  • thanks.  yes, it's a device app, and accuracy is checked later on, in the onPosition handler.  minfo is just the info part passed from onPosition.  I found that it helped to initialize the points as soon as possible in my app, so that I can begin to conduct calculations on them, such as distance and direction and so on.

    function onPosition(info) { 
        if ( (info != null) && (info.accuracy != null) ) { 
    
        if ( fitSession != null ) { 
        
            //! do normal program processing here
    
        } else { //! if fitSession has not been started yet, keep saving over all "Start" points
            if( (info.accuracy >= 2) && (info.position != null) ) {
            	initiatePoints(info); 
            }
        }

  • If you are recording in your app, you may want to use startLocation to initialize things.  

  • After initializing those pointA, pointB and so on, I was changing a variable pointsInitialized = true, and I was using that variable as a precondition for other functionalities in my watch app... 

    I can see how waiting until (info.startLocation != null) and initializing points after, or using startLocation as the initial value probably would be a tad simpler. 

    But I anticipate some users wanting to start their program before they get to the "start" location (i.e., what if there was poorer signal reception at the start location), hence I don't want to use it as my initial value for those points..

  • IMO, you should avoid calling the special initialize function directly. It isn't intended to be called explicitly like that.

  • Could you please tell me what the preferred method of changing the position data is? Do you mean using Position.parse?

    I need to set the waypoints to randomized positions, not just where the user currently is located at.  Also, I need to periodically change those waypoints at different times during the activity.

    I didn't plan to use any "waypoints" or persisted content, because I don't want it persisting in the app after I am done running the app.

  • This kind of depends on your app.  In mine, I keep lat/lon pairs for things, and I can always get the current lat/lon from GPS.

    Makes doing things like  "found" a bit easier, as a compare like that you really want to do "within a certain distance", as even if you stand in the exact same spot a second time, the lat/lon (the location) with be slightly different.