using MCSharp; using System; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms; using System.Threading; using System.Runtime.Serialization; using System.Runtime.Remoting.Messaging; [Serializable()] public class LifeForm:System.Windows.Forms.Form, ISerializable { //-------------- MCsharp functions ----------- public LifeForm ( ) { mcsharp_initiate(); } public LifeForm ( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.UnPack ( info, context, this ); mcsharp_initiate(); } public void GetObjectData ( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.Pack ( info, context, this ); } public void mcsharp_initiate ( ) { Monitor.Enter ( CommExec.Objects ); int mcObjectNumber = CommExec.Objects.Count + 1; CommExec.Objects.Add ( mcObjectNumber, this ); Monitor.Exit ( CommExec.Objects ); } int nComputers = 2 ; int width = 80 ; int height = 40 ; int nFrames = 100 ; Bitmap curPicture = new Bitmap( 1 , 1 ) ; Thread receiverThread ; Life l = new Life( ) ; public LifeForm ( int nComputers, int width, int height, int nFrames ) { mcsharp_initiate(); this.nComputers = nComputers ; this.width = width ; this.height = height ; this.nFrames = nFrames ; l.Calculate( l.c , nComputers , width , height , nFrames ) ; this.Text = "Life demo" ; this.Width = width * 4 ; this.Height = ( height * nComputers ) * 4 ; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen ; receiverThread = new Thread( new ThreadStart( Receiver ) ) ; receiverThread.Start( ) ; } public void Receiver ( ) { while ( true ) { curPicture = (Bitmap)l.Get( ) ; Repaint( ) ; } } private void Repaint ( ) { Monitor.Enter( this ) ; Graphics g = this.CreateGraphics( ) ; g.DrawImage( curPicture , 0 , 0 , ClientSize.Width , ClientSize.Height ) ; Monitor.Exit( this ) ; } protected override void OnPaint ( PaintEventArgs e ) { Repaint( ) ; } protected override void OnClosed ( EventArgs e ) { try { if ( receiverThread != null ) receiverThread.Abort( ) ; } catch { } ; } public static void Main ( string[] args ) { if ( ! MCSharp.Session.Init ( args ) ) return; Main_MCSharp_Wrapper ( args ); MCSharp.Session.FinalizeIt(); } private static void Main_MCSharp_Wrapper ( string[] args ) { try { int nComputers = Int32.Parse( args[ 0 ] ) ; int width = Int32.Parse( args[ 1 ] ) ; int height = Int32.Parse( args[ 2 ] ) ; int nFrames = Int32.Parse( args[ 3 ] ) ; Application.Run( new LifeForm( nComputers , width , height , nFrames ) ) ; } catch ( Exception e ) { Console.WriteLine( e.ToString( ) ) ; Console.WriteLine( "\nUsage: Life.exe nComputers width height nFrames\n" ) ; } } } [Serializable()] public class Life:System.Windows.Forms.Form, ISerializable { //-------------- MCsharp functions ----------- public Life ( ) { mcsharp_initiate(); } public Life ( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.UnPack ( info, context, this ); mcsharp_initiate(); } public void GetObjectData ( SerializationInfo info, StreamingContext context ) { MCSharp.Serialization.Pack ( info, context, this ); } public void mcsharp_initiate ( ) { Monitor.Enter ( CommExec.Objects ); int mcObjectNumber = CommExec.Objects.Count + 1; CommExec.Objects.Add ( mcObjectNumber, this ); Monitor.Exit ( CommExec.Objects ); c = new Channel ( this, mcObjectNumber, "mcsharpChannelc" ); mcsharpQueueGet = new MCSharp.ThreadQ(); } public Bitmap Filter ( Bitmap initBmp ) { Color trueColor = Color.White ; int tCi = trueColor.ToArgb( ) ; Color falseColor = Color.Black ; int fCi = falseColor.ToArgb( ) ; int width = initBmp.Width ; int height = initBmp.Height ; initBmp.SetPixel( 0 , 1 , Color.White ) ; Bitmap finalBmp = new Bitmap( width , height - 2 , PixelFormat.Format16bppRgb555 ) ; for ( int i = 0 ; i < width ; i++ ) { for ( int j = 1 ; j < height - 1 ; j++ ) { int curCells = 0 ; if ( initBmp.GetPixel( i , j - 1 ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( i , j + 1 ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( ( width + i - 1 ) % width , j ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( ( width + i - 1 ) % width , j - 1 ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( ( width + i - 1 ) % width , j + 1 ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( ( i + 1 ) % width , j ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( ( i + 1 ) % width , j - 1 ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( ( i + 1 ) % width , j + 1 ).ToArgb( ) == tCi ) curCells++ ; if ( initBmp.GetPixel( i , j ).ToArgb( ) == tCi ) { if ( curCells == 2 || curCells == 3 ) finalBmp.SetPixel( i , j - 1 , trueColor ) ; } else if ( curCells == 3 ) finalBmp.SetPixel( i , j - 1 , trueColor ) ; else { finalBmp.SetPixel( i , j - 1 , falseColor ) ; } } } return finalBmp ; } public Bitmap Randomize ( int width, int height ) { Bitmap bmp = new Bitmap( width , height , PixelFormat.Format16bppRgb555 ) ; Random r = new Random( ) ; for ( int i = 0 ; i < width ; i++ ) for ( int j = 0 ; j < height ; j++ ) bmp.SetPixel( i , j , GetColor( r.Next( 2 ) ) ) ; return bmp ; } public Color GetColor ( int code ) { if ( code == 0 ) return Color.Black ; else return Color.White ; } public Bitmap ConcatBitmaps ( Bitmap lineUp, Bitmap middle, Bitmap lineDown ) { Bitmap bmp = new Bitmap( middle.Width , middle.Height + 2 , PixelFormat.Format16bppRgb555 ) ; Graphics g = Graphics.FromImage( bmp ) ; g.DrawImageUnscaled( lineUp , 0 , 0 ) ; g.DrawImageUnscaled( middle , 0 , 1 ) ; g.DrawImageUnscaled( lineDown , 0 , middle.Height ) ; return bmp ; } public Bitmap GetFirstRow ( Bitmap bmp ) { Bitmap fr = new Bitmap( bmp.Width , 1 , PixelFormat.Format16bppRgb555 ) ; for ( int i = 0 ; i < bmp.Width ; i++ ) fr.SetPixel( i , 0 , bmp.GetPixel( i , 0 ) ) ; return fr ; } public Bitmap GetLastRow ( Bitmap bmp ) { Bitmap lr = new Bitmap( bmp.Width , 1 , PixelFormat.Format16bppRgb555 ) ; for ( int i = 0 ; i < bmp.Width ; i++ ) lr.SetPixel( i , 0 , bmp.GetPixel( i , bmp.Height - 1 ) ) ; return lr ; } public void CalculatePiece ( BDChannel prevForSending, BDChannel prevForReceiving, BDChannel nextForSending, BDChannel nextForReceiving, BDChannel firstForSending, BDChannel firstForReceiving, BDChannel signals, BDChannel results, int nComputers, int curComputer, int width, int height ) { MCSharp.TCP.DeliverMovableMethod ( this,"CalculatePiece_Body_MCSharpWrapper", new object[] {prevForSending, prevForReceiving, nextForSending, nextForReceiving, firstForSending, firstForReceiving, signals, results, nComputers, curComputer, width, height} ); } public void CalculatePiece_Body_MCSharpWrapper ( BDChannel prevForSending, BDChannel prevForReceiving, BDChannel nextForSending, BDChannel nextForReceiving, BDChannel firstForSending, BDChannel firstForReceiving, BDChannel signals, BDChannel results, int nComputers, int curComputer, int width, int height ) { BDChannel signalsForSending = new BDChannel( ) ; if ( curComputer < nComputers - 1 ) { nextForSending = new BDChannel( ) ; nextForReceiving = new BDChannel( ) ; CalculatePiece( nextForReceiving , nextForSending , null , null , firstForSending , firstForReceiving , signalsForSending , results , nComputers , curComputer + 1 , width , height ) ; } else { nextForSending = firstForReceiving ; nextForReceiving = firstForSending ; } Bitmap bmp = Randomize( width , height ) ; while ( ( (int)( signals.Receive( )[ 0 ] ) ) != -1 ) { results.Send( new object[ ]{ curComputer , bmp } ) ; if ( curComputer < nComputers - 1 ) signalsForSending.Send( 1 ) ; Bitmap fr = GetFirstRow( bmp ) ; Bitmap lr = GetLastRow( bmp ) ; prevForSending.Send( fr ) ; nextForSending.Send( lr ) ; fr = (Bitmap)( prevForReceiving.Receive( )[ 0 ] ) ; lr = (Bitmap)( nextForReceiving.Receive( )[ 0 ] ) ; bmp = Filter( ConcatBitmaps( fr , bmp , lr ) ) ; } if ( curComputer < nComputers - 1 ) signalsForSending.Send( -1 ) ; } public void Calculate ( Channel c, int nComputers, int width, int height, int nFrames ) { MCSharp.TCP.DeliverMovableMethod ( this,"Calculate_Body_MCSharpWrapper", new object[] {c, nComputers, width, height, nFrames} ); } public void Calculate_Body_MCSharpWrapper ( Channel c, int nComputers, int width, int height, int nFrames ) { BDChannel firstForSending = new BDChannel( ) ; BDChannel firstForReceiving = new BDChannel( ) ; BDChannel signals = new BDChannel( ) ; BDChannel results = new BDChannel( ) ; CalculatePiece( firstForSending , firstForReceiving , null , null , firstForSending , firstForReceiving , signals , results , nComputers , 0 , width , height ) ; Bitmap bmp = new Bitmap( width , height * nComputers ) ; Graphics g = Graphics.FromImage( bmp ) ; g.Clear( Color.Black ) ; for ( int j = 0 ; j < nFrames ; j++ ) { signals.Send( 1 ) ; for ( int i = 0 ; i < nComputers ; i++ ) { object[] o = (object[])results.Receive( ) ; g.DrawImageUnscaled( (Bitmap)o[ 1 ] , 0 , height * ( (int)o[ 0 ] ) ) ; } c.Send( bmp ) ; } signals.Send( -1 ) ; } //-------------Channel declarations----------------- [NonSerialized] public MCSharp.Channel c; //-------------Queues------------------------------ [NonSerialized] private MCSharp.ThreadQ mcsharpQueueGet; //-------------Masks-------------------------------- private const int mcsharp_mask_Get = 1 << 0; private const int mcsharp_mask_c = 1 << 1; private const int mcsharp_mask_Getc = mcsharp_mask_Get | mcsharp_mask_c; [NonSerialized] private MCSharp.BitMask mcsharpBitMaskGetc = new MCSharp.BitMask(); private void scanGetc () { if ( mcsharpBitMaskGetc.match ( mcsharp_mask_Getc ) ) mcsharpQueueGet.wakeup(); } [OneWay] public void mcsharpChannelc ( Bitmap bmp ) { lock ( mcsharpQueueGet ) { c.Enqueue ( new object [] { bmp } ); if ( ! mcsharpBitMaskGetc.match ( mcsharp_mask_c ) ) { mcsharpBitMaskGetc.set ( mcsharp_mask_c ); scanGetc (); } } } public Bitmap Get ( ) { Monitor.Enter ( mcsharpQueueGet ); if ( ! mcsharpBitMaskGetc.match ( mcsharp_mask_Get ) ) goto now; later: mcsharpQueueGet.yield ( mcsharpQueueGet ); if ( mcsharpQueueGet.empty ) mcsharpBitMaskGetc.clear ( mcsharp_mask_Get ); now: if ( mcsharpBitMaskGetc.match ( mcsharp_mask_c ) ) { object[] oc = ( object[] ) c.Dequeue(); Bitmap bmp = ( Bitmap ) oc [ 0 ]; if ( c.Count == 0 ) mcsharpBitMaskGetc.clear ( mcsharp_mask_c ); scanGetc (); Monitor.Exit ( mcsharpQueueGet ); { return bmp ; } } else { mcsharpBitMaskGetc.set ( mcsharp_mask_Get ); goto later; } } }