Java controller / Frege model

Showing 1-13 of 13 messages
Java controller / Frege model griba 6/7/12 7:32 AM
This is what I was looking for
and now it works !!

There is a Java ModelRoot class where to hook the Frege structure

The previously shown JFregeListIterator to retrieve the result list

The Model.fr with actions perfomed with ST.performUnsafe
(in this case 
    * modelInit hooks a list with 3 records to ModelRoot
    * modelAdd  call to prepend a new record with data from the Java caller
    * modelGetListIterator to get a result list iterator

Then, the Java JMain test class that calls the model actions.

To check it all just run at the unix prompt:

sh build.sh
-----------------
Maybe it can be done otherwise and I would like any criticism.

Later I will make an Android app with this.

Cheers!
Gabriel Riba.

Re: Java controller / Frege model griba 6/7/12 2:52 PM
Here it is in the Android Market !!!


If the link does not work because of line wrapping cuts, look for Frege in the Android market and you will see the Frege project logo.

Here I ask permission to use the "Frege project logo" for the sample app.

Cheers!

Gabriel Riba.

El dijous 7 de juny de 2012 16:32:42 UTC+2, griba va escriure:
Re: Java controller / Frege model griba 6/9/12 4:20 AM
Android app. updated to a Handset friendly vertical layout.

I think that I should use IO.performUnsafe in the Model.fr instead of ST.performUnsafe but as IO is a synonim of (ST RealWorld) there is no difference of behaviour (If I'm not wrong!).

Cheers!
Gabriel.


El dijous 7 de juny de 2012 16:32:42 UTC+2, griba va escriure:
This is what I was looking for
Re: Java controller / Frege model Ingo W. 6/9/12 4:17 PM


Am Samstag, 9. Juni 2012 13:20:50 UTC+2 schrieb griba:
Android app. updated to a Handset friendly vertical layout.

I think that I should use IO.performUnsafe in the Model.fr instead of ST.performUnsafe but as IO is a synonim of (ST RealWorld) there is no difference of behaviour (If I'm not wrong!).

Hi Gabriel,

it's actually no difference, except for readability.
Unfortunately, I couldn't install the app on my phone, I guess my Android version is too old. Oh well, my phone is more than a year old ....

Anyway, great work!

Re: Java controller / Frege model griba 6/10/12 2:44 AM
>> Unfortunately, I couldn't install the app on my phone, I guess my Android version is too old. Oh well, my phone is more than a year old ....

The lowest Android SDK available for Java6 is v.2.3.3 which is API level 10. (Android 2.3.0 (API level 9) has been discontinued).

The sets compatible are tablets with Android 3.0+, or more recent handsets and tablets with Android 2.3.3.

Regards.
Gabriel Riba.

El diumenge 10 de juny de 2012 1:17:34 UTC+2, Ingo W. va escriure:
Re: Java controller / Frege model griba 6/10/12 3:09 AM
Here are the Android controller and the updated Model.fr

// ------------------------------------------
package com.xarxaire.griba.fregedemo;


import com.xarxaire.griba.fregedemo.R;  // resources

import com.xarxaire.griba.fregedemo.Model ;
import com.xarxaire.griba.fregedemo.Model.TSample ;
import com.xarxaire.griba.fregedemo.JFregeIterator ;
import frege.rt.Box ;

// ... other android and Java imports

public class Android_FregeDemoActivity extends Activity {
public final static String CITY = "city" ;
public final static String CTDATA = "ctdata" ;
final String [] FROM     = {CITY, CTDATA,} ;
final int [] TO       = {R.id.city, R.id.ctdata, } ;
    final static Box.Int unit = Box.Int.mk(0) ;
ListView myListView ;
 
LinkedList<TreeMap<String, ?>> rowList ;
EditText etCity, etCityData ;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
     myListView = (ListView) findViewById(R.id.mylist) ;
     myListView.setOnItemClickListener(new MyListHandler( this)) ;
     
     etCity = (EditText) findViewById(R.id.etCity) ;;
     etCityData = (EditText) findViewById(R.id.etCityData) ;
     
     Model.modelInit( unit) ;

    }
    
    @Override
    public void onStart() {
    showModelData() ;
    super.onStart() ;
    }
  
public void addToList(View v) {
String city = etCity.getText().toString() ;
String ctData = etCityData.getText().toString() ;
int intCityData = Integer.valueOf( ctData) ;
myModelAdd( city, intCityData) ;
}
    
    
    private void myModelAdd(String city, int ctdata) {
        Model.modelAdd( Box.<String>mk(city), Box.Int.mk(ctdata)) ;
        showModelData() ;
        Toast.makeText(this, "Added in the Frege model", Toast.LENGTH_LONG).show() ;
    }
    
private void myModelRemove( String city) {
        Model.modelRemove( Box.<String>mk(city)) ;
        showModelData() ;
        Toast.makeText(this, "Removed in the Frege model", Toast.LENGTH_LONG).show() ;
    }
    
    @SuppressWarnings("rawtypes")
private void showModelData() {
   
        @SuppressWarnings("unchecked")
JFregeIterator<TSample> iter = (JFregeIterator<TSample>) ((Box<JFregeIterator>) Model.modelGetListIterator( unit)).j ;

        rowList = new LinkedList<TreeMap<String, ?>>() ; 
        TreeMap<String, Object> row ;
        
        
        while (iter.hasNext()) {
        row = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER) ;

            try {
TSample obj = (TSample) iter.next() ; 
String city = TSample.city( obj) ;
int ctdata = TSample.amount( obj) ;
row.put( CITY, city) ;
row.put( CTDATA, ctdata) ;
rowList.addLast( row) ;
            }
            catch (NoSuchElementException e) {
            // no envisaged
                System.out.println( e.getMessage()) ;
            }  
        }

     // Set up data binding
    SimpleAdapter adapter = new SimpleAdapter (this, rowList, R.layout.item, FROM, TO) ;
    myListView.setAdapter(adapter);
  }
    
    class MyListHandler implements OnItemClickListener {
    Context ctx ;
    MyListHandler( Context ctx) {
    this.ctx = ctx ;
    }

public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
final String myCity = (String) rowList.get((int) id).get(CITY) ;
// Delete confirmation
new AlertDialog.Builder(ctx)
       .setIcon(android.R.drawable.ic_dialog_alert)
       .setTitle("Confirm delete")
       .setMessage("Delete entry \""+myCity+"\" ?")
       .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

           public void onClick(DialogInterface dialog, int which) {

            myModelRemove( myCity) ;    
           }
       })
       .setNegativeButton(android.R.string.no, null)
       .show();
}
    }
}
// ------------------------------------------
// ------------------------------------------

--------------------------------------------
-- Model.fr
--------------------------------------------
module com.xarxaire.griba.fregedemo.Model where

data MyJFregeIterator s = native JFregeIterator where
    pure native new JFregeIterator.getInstance :: [t] -> (MyJFregeIterator s)

data Sample = Sample {city::String, amount::Int}
derive Eq Sample 

sampleList = [Sample "Paris" 2, Sample "Berlin" 3, Sample  "Barcelona" 1]
    
data JModelRoot myStructure s = native ModelRoot where
        -- instance methods
        native getModelStructure :: JModelRoot myStructure RealWorld -> IO myStructure
        native setModelStructure :: JModelRoot myStructure RealWorld -> myStructure -> IO ()

type MyStructure = [Sample] 
type MyModelRoot = JModelRoot MyStructure RealWorld
        
-- static methods
native jmrInitSingleton ModelRoot.initSingleton :: MyStructure -> IO MyModelRoot
native jmrGetInstance ModelRoot.getInstance :: () -> IO (Maybe MyModelRoot)

modelInit () = IO.performUnsafe (jmrInitSingleton( sampleList))

modelAdd :: String -> Int -> ()
modelAdd mycity amt = IO.performUnsafe (modelDoAdd mycity amt)

modelDoAdd :: String -> Int -> IO ()
modelDoAdd mycity amt 
= do
maybeInstance <- jmrGetInstance ()
case maybeInstance of
                Nothing -> error "you should initialise modelRoot first"
                Just modelRoot -> do {
myList <- modelRoot.getModelStructure ;
modelRoot.setModelStructure ((Sample mycity amt) : myList) ;
}

modelRemove myCity = IO.performUnsafe (modelDoRemove myCity)

modelDoRemove :: String -> IO ()
modelDoRemove myCity = do
maybeInstance <- jmrGetInstance ()
case maybeInstance of
                Nothing -> error "you should initialise modelRoot first"
                Just modelRoot -> do {
myList <- modelRoot.getModelStructure ;
let newList = filter (\(obj :: Sample) -> obj.city != myCity) myList
in modelRoot.setModelStructure (newList) ;
}

modelGetListIterator () = IO.performUnsafe (modelReturnListIterator ())

modelReturnListIterator :: () -> IO (MyJFregeIterator RealWorld)
modelReturnListIterator ()
= do
myInstance <- jmrGetInstance ()
case myInstance of
                Nothing -> error "you should initialise modelRoot first"
                Just modelRoot -> do {
myList <- modelRoot.getModelStructure ;
return (MyJFregeIterator.new (myList :: MyStructure)) ;
}
--------------------------------------------
--------------------------------------------

Thanks to you for the Frege compiler!!

I have problems with ''do'' subblocs parsing, so I used the semicolon separated syntax { ; ; }

Cheers!
Gabriel Riba.


El diumenge 10 de juny de 2012 1:17:34 UTC+2, Ingo W. va escriure:


Re: Java controller / Frege model griba 6/10/12 3:36 AM
The last sentence should not have had the type annotation, since it's a list (PreludeBase.TList) what was expected. It should be:

modelReturnListIterator :: () -> IO (MyJFregeIterator RealWorld)
modelReturnListIterator ()
= do
myInstance <- jmrGetInstance ()
case myInstance of
                Nothing -> error "you should initialise modelRoot first"
                Just modelRoot -> do {
myList <- modelRoot.getModelStructure ;
return (MyJFregeIterator.new myList) ;
}

-----
Cheers!


El diumenge 10 de juny de 2012 12:09:09 UTC+2, griba va escriure:
Re: Java controller / Frege model Ingo W. 6/10/12 3:36 AM


Am Sonntag, 10. Juni 2012 12:09:09 UTC+2 schrieb griba:
 
[ ... ]
I have problems with ''do'' subblocs parsing, so I used the semicolon separated syntax { ; ; }


This works, though it shouldn't be necessary.
Just make sure you don't use tabs for indentation.


Re: Java controller / Frege model griba 6/10/12 3:40 AM
I was wrong with my last post, as the type annotation was a list.

Sorry.

El diumenge 10 de juny de 2012 12:36:09 UTC+2, griba va escriure:
Re: Java controller / Frege model griba 6/10/12 5:00 AM
Is there an established way to make a function from a data record named field ?

I have updated the code to get a sorted list result, so the last Model function looks like:

modelReturnListIterator :: () -> IO (MyJFregeIterator RealWorld)
modelReturnListIterator () = do
maybeInstance <- jmrGetInstance ()
case maybeInstance of
                Nothing -> error "you should initialise modelRoot first"
                Just modelRoot -> modelReturnListIteratorOverSortedStructure modelRoot
 

modelReturnListIteratorOverSortedStructure (modelRoot::JModelRoot MyStructure RealWorld) = do
    myList <- modelRoot.getModelStructure 
    return (MyJFregeIterator.new (sortBy (comparing sampleCity) myList)) 
  where
      sampleCity (obj::Sample) = obj.city 
---------------------------------------------------------------
Regards.

El diumenge 10 de juny de 2012 12:36:37 UTC+2, Ingo W. va escriure:
Re: Java controller / Frege model Ingo W. 6/10/12 6:24 AM


Am Sonntag, 10. Juni 2012 14:00:31 UTC+2 schrieb griba:
Is there an established way to make a function from a data record named field ?

In your case here: Sample.city
Generally, T.f, where T is the type constructor of the record and f is the field name.
 

Re: Java controller / Frege model griba 6/10/12 7:27 AM
The editor in Eclipse introduces tabs by default  that cause the parsing problems with ''do'' subblocs.

I have seen that the eclipse preferences for Frege has a Checkbox named "Tab inserts spaces" that is unchecked by default. 

Maybe the FregeIDE setup page should advise to check the checkbox.

-----------------------------------------------------------------------------------------------
Now, introducing (>>>) the arrow left-to-right function composition the code is cleaner:

import Data.List (sortBy)

data MyJFregeIterator s = native JFregeIterator where
    pure native new JFregeIterator.getInstance :: [t] -> (MyJFregeIterator s)

data Sample = Sample {city::String, amount::Int}
derive Eq Sample 

sampleList = [Sample "Paris" 2, Sample "Berlin" 3, Sample  "Barcelona" 1]
    
data JModelRoot myStructure s = native ModelRoot where
        -- instance methods
        native getModelStructure :: JModelRoot myStructure RealWorld -> IO myStructure
        native setModelStructure :: JModelRoot myStructure RealWorld -> myStructure -> IO ()

type MyStructure = [Sample] 
type MyModelRoot = JModelRoot MyStructure RealWorld
        
-- static methods
native jmrInitSingleton ModelRoot.initSingleton :: MyStructure -> IO MyModelRoot
native jmrGetInstance ModelRoot.getInstance :: () -> IO (Maybe MyModelRoot)

modelInit () = IO.performUnsafe (jmrInitSingleton( sampleList))

infixr 3 `>>>`  
f >>> g = g • f

modelAdd :: String -> Int -> ()
modelAdd mycity amt = IO.performUnsafe (modelDoAdd mycity amt)

modelDoAdd :: String -> Int -> IO ()
modelDoAdd mycity amt = do
  maybeInstance <- jmrGetInstance ()
  case maybeInstance of
    Nothing -> error "you should initialise modelRoot first"
    Just modelRoot ->  
         modelRoot.getModelStructure >>= ((Sample mycity amt :) >>> modelRoot.setModelStructure)

modelRemove myCity = IO.performUnsafe (modelDoRemove myCity)

modelDoRemove :: String -> IO ()
modelDoRemove myCity = do
  maybeInstance <- jmrGetInstance ()
  case maybeInstance of
    Nothing -> error "you should initialise modelRoot first"
    Just modelRoot -> do 
        modelRoot.getModelStructure >>= ((filter notMyCity) >>> modelRoot.setModelStructure)   
      where
        -- pointFree
        notMyCity = Sample.city >>> (!= myCity)  

modelGetListIterator () = IO.performUnsafe (modelReturnListIterator ())

modelReturnListIterator :: () -> IO (MyJFregeIterator RealWorld)
modelReturnListIterator () = do
  maybeInstance <- jmrGetInstance ()
  case maybeInstance of
    Nothing -> error "you should initialise modelRoot first"
    Just modelRoot ->
       modelRoot.getModelStructure >>= (sortBy (comparing Sample.city) >>> MyJFregeIterator.new >>> return)

----------------------------------------------------------------------------
Regards!


El diumenge 10 de juny de 2012 15:24:51 UTC+2, Ingo W. va escriure:
Re: Java controller / Frege model Ingo W. 6/10/12 12:43 PM


Am Sonntag, 10. Juni 2012 16:27:00 UTC+2 schrieb griba:
The editor in Eclipse introduces tabs by default  that cause the parsing problems with ''do'' subblocs.

I have seen that the eclipse preferences for Frege has a Checkbox named "Tab inserts spaces" that is unchecked by default.

No, it should be  checked by default.
The trouble is that too many preferences (General Editor, Java Editor, IMP Editor, Language Specific Editor) influence this.

 
Maybe the FregeIDE setup page should advise to check the checkbox.

Yes, I think I'll make it clear in the  tutorial more explicitly.