.. index:: 
	single: What is new in Ring 1.9?; Introduction

========================
What is new in Ring 1.9?
========================

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

.. index:: 
	pair: What is new in Ring 1.9?; List of changes and new features

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

.. index:: 
	pair: What is new in Ring 1.9?; New Game : Gold Magic 800

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

.. image:: gmshot2.png
	:alt: Gold Magic 800 - Screen Shot 2

The next screen shot for level (1)

.. image:: gmshot3.png
	:alt: Gold Magic 800 - Screen Shot 3

The Gold Magic 800 Level Editor 

.. image:: gmleveleditor.png
	:alt: Gold Magic 800 Level Editor

.. index:: 
	pair: What is new in Ring 1.9?; More Games 

More Games
==========

The next games are added to Ring Applications 

(1) The 2048 Game
(2) The Memory Game
(3) The Wise Quadrat Game 
(4) The Tessera Game
(5) The Othello Game

The next screen shot for the 2048 game on Android 

.. image:: game2048_shot1.png
	:alt: 2048 Game

The next screen shot for the Tessera game

.. image:: tesseragame.png
	:alt: Tessera Game

The next screen shot for the Othello game

.. image:: othellogame.png
	:alt: Othello Game


.. index:: 
	pair: What is new in Ring 1.9?; Better Ring Notepad 

Better Ring Notepad
===================

(1) New Style
(2) New Mode
(3) Tabs for opened files 
(4) Support executing batch files 

.. image:: rnote19.jpg
	:alt: Ring Notepad


.. index:: 
	pair: What is new in Ring 1.9?; Better StdLib

Better StdLib
=============

(1) 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:

.. code-block:: ring

	load "stdlibcore.ring"
	aList = 1:10
	? list2Code(aList)

Output:

.. code-block:: ring

	[
		1,2,3,4,5,6,7,8,9,10
	]


(2) 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:

.. code-block:: ring

	load "stdlibcore.ring"

	cStr = "MmMm"

	aList = Str2ASCIILIST(cStr)
	? aList 

	cStr2 = ASCIIList2Str(aList)
	? cStr2
	? len(cStr2)

Output:

.. code-block:: none

	77
	109
	77
	109

	MmMm
	4



.. index:: 
	pair: What is new in Ring 1.9?; BigNumber Library

BigNumber Library
=================

Using the BigNumber library we can do arithmetic operations on huge numbers.

Example:

.. code-block:: ring

	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:

.. code-block:: none

	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

.. index:: 
	pair: What is new in Ring 1.9?; RingPostgreSQL Extension

RingPostgreSQL Extension
========================

Ring 1.9 provide native support for PostgreSQL database using the RingPostgreSQL Extension.

Example:

.. code-block:: ring

	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:

.. code-block:: none

	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

.. index:: 
	pair: What is new in Ring 1.9?; Deploying Web applications in the Cloud

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/

.. image:: ringincloud.png
	:alt: Ring Web Application in the Cloud

For more information check the Deploying Web Applications In The Cloud chapter in the documentation.

.. index:: 
	pair: What is new in Ring 1.9?; Better RingQt

Better RingQt
=============

(1) 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

(2) 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:

.. code-block:: ring

	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:

.. image:: printpreviewdialog.png
	:alt: Print Preview Dialog


.. index:: 
	pair: What is new in Ring 1.9?; Better Memory Management

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:

.. code-block:: ring

	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 

.. index:: 
	pair: What is new in Ring 1.9?; Better Code Generator for Extensions

Better Code Generator for Extensions
====================================

(1) The code generator for extensions is updated to support the <loadfile> command

.. code-block:: ring

	<loadfile> filename.cf

This is useful to separate the extension configuration file to many files

Example:

The file : qt_module_network.cf in the RingQt Extension

.. code-block:: ring

	<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

(2) 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 Garbage Collector will manage these C pointers.

Example

.. code-block:: ring

	<class>
	name: QFont
	para: QString, int, int, bool
	managed
	</class>

.. index:: 
	pair: What is new in Ring 1.9?; More Improvements

More Improvements
=================

(1)  Ring Compiler - The Rule (Factor -> '-' Expr) changed to (Factor -> '-' Factor).
(2)  Ring VM - Better Error Message.
(3)  Better code for IsNULL() function - updated to check pointers too.
(4)  Better code for ringvm_evalinscope() function - used by the Trace Library.
(5)  Better code for Space() function.
(6)  Better code for Hex() and Dec() functions.
(7)  Better code for Download() function.
(8)  Better code for SubStr() function.
(9)  Better code for the Unsigned() function.
(10) Better code for Chdir() function.
(11) Better code for Tempname() function.
(12) Better code for HashTable - New Key (using ring_strdup() instead of strdup() function).
(13) New Function : SRandom() - Initialize random number generator. 
(14) New Function : IsPointer().
(15) IsList() will not return True for C Pointers, we have now the IsPointer() function. 
(16) The ? Operator is updated to respect the ringvm_see() function.
(17) Scripts to run Ring tests on Linux and macOS (Not only Windows).
(18) RingAllegro is Updated from Allegro 5.1 to Allegro 5.2.
(19) Shader Functions are added to RingAllegro.
(20) Joystick Functions are added to RingAllegro.
(21) Network functions are added to RingLibSDL.
(22) Game Engine for 2D Games - Text Class - Check the font object before usage.
(23) Game Engine for 2D Games - Automatic support for Joystick.
(24) RingLibCurl is updated to automatically use CURLOPT_COPYPOSTFIELDS when needed.
(25) Ring Notepad - Find Previous Feature.
(26) Ring Notepad - Default Style. 
(27) Ring Notepad - Support using Non-English language (Like Arabic) in file names.
(28) Form Designer - Nice Alignment for Toolbox Icons.
(29) Form Desginer - QAllEvents Class - Mouse Double Click Event.
(30) Find in Files - Replace and Replace All options.
(31) Qt Class Converter is updated for better conversion results.
(32) More samples are added to ring/samples/other folder.
(33) Code Refactoring for Ring Notepad, RingQt, Game Engine for 2D Games.
(34) Better Documentation - Many images are updated to reflect the current state of Ring Environment.
(35) Better Documentation - More chapters are added to the documentation.