What is new in Ring 1.9?¶

In this chapter we will learn about the changes and new features in Ring 1.9 release.

List of changes and new features¶ Ring 1.9 comes with the next features! New Game : Gold Magic 800

More Games

Better Ring Notepad

Better StdLib

BigNumber Library

RingPostgreSQL Extension

Deploying Web applications in the Cloud

Better RingQt

Better Memory Management

Better Code Generator for Extensions

More Improvements

New Game : Gold Magic 800¶ The Gold Magic 800 is a new puzzle game. Ring 1.9 comes with the Demo Version (18 Levels) and the game source code. Steam Page (44 Levels) : https://store.steampowered.com/app/939200/Gold_Magic_800/ We can select the level The next screen shot for level (1) The Gold Magic 800 Level Editor

More Games¶ The next games are added to Ring Applications The 2048 Game The Memory Game The Wise Quadrat Game The Tessera Game The Othello Game The next screen shot for the 2048 game on Android The next screen shot for the Tessera game The next screen shot for the Othello game

Better Ring Notepad¶ New Style New Mode Tabs for opened files Support executing batch files

Better StdLib¶ The List2Code() function is added to the StdLib This function convert a Ring list during the runtime to Ring source code that we can save to source files. The list may contains strings, numbers or sub lists. Example: load "stdlibcore.ring" aList = 1 : 10 ? list2Code ( aList ) Output: [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] The Str2ASCIIList() and ASCIIList2Str() are added to the StdLib Using these functions we can convert between string of bytes and a list of numbers where each item represent the ASCII code of one byte in the string. So we may convert a string of bytes to ASCII List then do some operations on the list numbers (Like XOR) Example: load "stdlibcore.ring" cStr = "MmMm" aList = Str2ASCIILIST ( cStr ) ? aList cStr2 = ASCIIList2Str ( aList ) ? cStr2 ? len ( cStr2 ) Output: 77 109 77 109 MmMm 4

BigNumber Library¶ Using the BigNumber library we can do arithmetic operations on huge numbers. Example: load "bignumber.ring" num1 = "62345678901234567891678345123456789" ### Big num2 = "1237894567890123419871236545" ### Small num3 = "64" ### Divide Small num4 = "765432" num5 = "3" ### Power ? "Add big numbers:" a1 = new BigNumber ( num1 ) a1 . Print () a2 = new BigNumber ( num2 ) a2 . Print () a3 = a1 + a2 a3 . Print () ? nl ? "Substract big numbers:" a1 = new BigNumber ( num1 ) a1 . Print () a2 = new BigNumber ( num2 ) a2 . Print () a3 = a1 - a2 a3 . Print () ? nl ? "Multiply big numbers:" a1 = new BigNumber ( num1 ) a1 . print () a2 = new BigNumber ( num2 ) a2 . print () a3 = a1 * a2 a3 . print () ? nl ? "Divide big numbers:" a1 = new BigNumber ( num1 ) a1 . print () a2 = new BigNumber ( num2 ) a2 . print () a3 = a1 / a2 a3 . print () ? nl ? "Divide big numbers: by very small number" a1 = new BigNumber ( num1 ) a1 . print () a2 = new BigNumber ( num3 ) a2 . print () a3 = a1 / a2 a3 . print () ? nl ? "Power of big number:" a1 = new BigNumber ( num1 ) a1 . print () a2 = new BigNumber ( num5 ) a2 . print () a3 = a1 ^ a2 a3 . print () ? nl Output: Add big numbers: 62345678901234567891678345123456789 1237894567890123419871236545 62345680139129135781801764994693334 Substract big numbers: 62345678901234567891678345123456789 1237894567890123419871236545 52345687663340000001554925252220244 Multiply big numbers: 62345678901234567891678345123456789 1237894567890123419871236545 77177377243260150103462178714197454736432472780119682305154005 Divide big numbers: 62345678901234567891678345123456789 1237894567890123419871236545 50364288 Divide big numbers: by very small number 62345678901234567891678345123456789 64 974151232831790123307474142554012 Power of big number: 62345678901234567891678345123456789 3 242336636261471172092347146031727004 (Output continue in next line) 371698195628343934238988256152289508 (Output continue in next line) 493964611043228971692389860897069 For more information check the BigNumber Library Chapter in the documentation

RingPostgreSQL Extension¶ Ring 1.9 provide native support for PostgreSQL database using the RingPostgreSQL Extension. Example: load "postgresqllib.ring" conninfo = "user=postgres password=sa dbname = mahdb" exit_nicely = func conn { PQfinish ( conn ) shutdown ( 1 ) } conn = PQconnectdb ( conninfo ) if ( PQstatus ( conn ) != CONNECTION_OK ) fputs ( stderr , "Connection to database failed: " + PQerrorMessage ( conn )) call exit_nicely ( conn ) ok res = PQexec ( conn , " DROP DATABASE mahdb ; ") if PQresultStatus ( res ) != PGRES_TUPLES_OK fputs ( stderr , "Remove failed: " + PQerrorMessage ( conn )) PQclear ( res ) ok PQclear ( res ) res = PQexec ( conn , "CREATE DATABASE mahdb;" ) if PQresultStatus ( res ) != PGRES_TUPLES_OK fputs ( stderr , "Create database failed: " + PQerrorMessage ( conn )) PQclear ( res ) ok res = PQexec ( conn , " CREATE TABLE COMPANY ( ID INT PRIMARY KEY NOT NULL , NAME TEXT NOT NULL , AGE INT NOT NULL , ADDRESS CHAR ( 50 ), SALARY REAL ); ") if PQresultStatus ( res ) != PGRES_TUPLES_OK fputs ( stderr , "Create Table failed: " + PQerrorMessage ( conn )) PQclear ( res ) ok PQclear ( res ) res = PQexec ( conn , " INSERT INTO COMPANY ( ID , NAME , AGE , ADDRESS , SALARY ) VALUES ( 1 , 'Mahmoud' , 31 , 'Jeddah' , 10.00 ), ( 2 , 'Ahmed' , 27 , 'Jeddah' , 20.00 ), ( 3 , 'Mohammed' , 33 , 'Egypt' , 30.00 ), ( 4 , 'Ibrahim' , 24 , 'Egypt ' , 40.00 ); ") if PQresultStatus ( res ) != PGRES_TUPLES_OK fputs ( stderr , "Insert Table failed: " + PQerrorMessage ( conn )) PQclear ( res ) ok PQclear ( res ) res = PQexec ( conn , " select * from COMPANY ") if PQresultStatus ( res ) != PGRES_TUPLES_OK fputs ( stderr , "Select failed: " + PQerrorMessage ( conn )) PQclear ( res ) call exit_nicely ( conn ) ok nFields = PQnfields ( res ) for i = 1 to nFields ? PQfname ( res , i - 1 ) next ? copy ( "*" , 60 ) for i = 1 to PQntuples ( res ) for j = 1 to nFields see PQgetvalue ( res , i - 1 , j - 1 ) + " " next see nl next PQclear ( res ) PQfinish ( conn ) Output: id name age address salary ************************************************************ 1 Mahmoud 31 Jeddah 10 2 Ahmed 27 Jeddah 20 3 Mohammed 31 Egypt 30 4 Ibrahim 24 Egypt 40 For more information check the PostgreSQL Chapter in the documentation

Deploying Web applications in the Cloud¶ We created a new project and tutorial to explain how to deploy Ring web applications in the Cloud using Heroku Demo : http://testring.herokuapp.com/ Project : https://github.com/ring-lang/RingWebAppOnHeroku Heroku Website : https://www.heroku.com/ For more information check the Deploying Web Applications In The Cloud chapter in the documentation.

Better RingQt¶ The next classes are added to RingQt QDrag

QMimeData

QDropEvent

QDragMoveEvent

QDragEnterEvent

QDragLeaveEvent

QClipboard

QChildEvent

QGeoPositionInfo

QGeoCoordinate

QGeoAddress

QGeoAreaMonitorInfo

QGeoAreaMonitorSource

QGeoCircle

QGeoPositionInfoSource

QGeoRectangle

QGeoShape

QGeoSatelliteInfo

QGeoSatelliteInfoSource

QNmeaPositionInfoSource

QAxWidget

QTextStream

QPrinterInfo

QPrintPreviewWidget

QPrintPreviewDialog

QPageSetupDialog

QAbstractPrintDialog

QPrintDialog The next classes are updated QAllEvents Class : New Events (ChildAdded, ChildPolished, ChildRemoved).

QPainter Class : Updated Methods (drawConvexPloygon, drawPoints, drawPolyline) Accept Ring list of points.

QVariant : More versions that accept different parameters when creating the object.

QAxBase : Different versions for the dynamicCall() and querySubObject() methods. The next example for using the QPrintPreviewDialog class Example: load "guilib.ring" new qApp { win1 = new qwidget () { setwindowtitle ( "Printer Preview Dialog" ) setgeometry ( 100 , 100 , 800 , 880 ) printer1 = new qPrinter ( 0 ) show () oPreview = new qPrintPreviewDialog ( printer1 ) { setParent ( win1 ) move ( 10 , 10 ) setPaintrequestedevent ( "printPreview()" ) exec () } } exec () } func printPreview printer1 { painter = new qpainter () { begin ( printer1 ) myfont = new qfont ( "Times" , 50 , - 1 , 0 ) setfont ( myfont ) drawtext ( 100 , 100 , "Test - Page (1)" ) printer1 . newpage () drawtext ( 100 , 100 , "Test - Page (2)" ) printer1 . newpage () myfont2 = new qfont ( "Times" , 14 , - 1 , 0 ) setfont ( myfont2 ) for x = 1 to 30 drawtext ( 100 , 100 + ( 20 * x ), "Number : " + x ) next endpaint () } } Screen Shot:

Better Memory Management¶ The Ring API is updated to include RING_API_RETMANAGEDCPOINTER() Using RING_API_RETMANAGEDCPOINTER() the Ring extensions written in C/C++ languages can return a managed pointer to Ring. This pointer can be controlled by the Ring VM using reference counting. This is important to avoid the need to write code that free the unmanaged resources like QPixMap objects in RingQt. Also the Code Generator for extensions is updated to automatically use RING_API_RETMANAGEDCPOINTER() based on need. Syntax: RING_API_RETMANAGEDCPOINTER ( void * pValue , const char * cPointerType , void ( * pFreeFunc )( void * , void * )) For more information about RING_API_RETMANAGEDCPOINTER() See the “Extension using the C/C++ languages” Chapter in the documentation

Better Code Generator for Extensions¶ The code generator for extensions is updated to support the <loadfile> command < loadfile > filename . cf This is useful to separate the extension configuraition file to many files Example: The file : qt_module_network.cf in the RingQt Extension < comment > Module ( network ) </ comment > < loadfile > qabstractsocket . cf < loadfile > qnetworkproxy . cf < loadfile > qtcpsocket . cf < loadfile > qtcpserver . cf < loadfile > qhostaddress . cf < loadfile > qhostinfo . cf < loadfile > qnetworkrequest . cf < loadfile > qnetworkaccessmanager . cf < loadfile > qnetworkreply . cf The code generator support the <managed> option when defining classes. Using this option, the generator will use RING_API_RETMANAGEDCPOINTER() to return the C pointer. So the Garabage Collector will manage these C pointers. Example < class > name : QFont para : QString , int , int , bool managed </ class >