.. index:: 
	single: Embedding Ring in Ring; Embedding Ring in Ring

======================
Embedding Ring in Ring
======================

In this chapter we will learn about embedding Ring in Ring programs and applications.

.. index:: 
	pair: Embedding Ring in Ring; Embedding Ring in Ring without sharing the State

Embedding Ring in Ring without sharing the State
================================================

From Ring 1.0 we already have functions for embedding Ring in the C language. Also we
can execute Ring code inside Ring programs using the eval() function. In this release
we provide functions for embedding Ring in Ring programs without sharing the state.

Advantages:

(1) Quick integration for Ring programs and applications together without conflicts.

(2) Execute and run Ring code in safe environments that we can trace.

Example:

.. code-block:: ring

	pState = ring_state_init()
	ring_state_runcode(pState,"See 'Hello, World!'+nl")
	ring_state_runcode(pState,"x = 10")

	pState2 = ring_state_init()
	ring_state_runcode(pState2,"See 'Hello, World!'+nl")
	ring_state_runcode(pState2,"x = 20")

	ring_state_runcode(pState,"see x +nl")
	ring_state_runcode(pState2,"see x +nl")

	v1 = ring_state_findvar(pState,"x")
	v2 = ring_state_findvar(pState2,"x")

	see v1[3] + nl
	see V2[3] + nl

	ring_state_delete(pState)
	ring_state_delete(pState2)

Output:

.. code-block:: ring

	Hello, World!
	Hello, World!
	10
	20
	10
	20

.. index:: 
	pair: Embedding Ring in Ring; Serial Execution of Programs

Serial Execution of Programs
============================

We can execute application after another application using ring_state_main()

Example:

.. code-block:: ring

	chdir(exefolder()+"/../applications/formdesigner")
	ring_state_main('formdesigner.ring')
	chdir(exefolder()+"/../applications/cards")
	ring_state_main('cards.ring')

.. index:: 
	pair: Embedding Ring in Ring; ring_state_setvar()

ring_state_setvar()
===================

Using ring_state_setvar() we can set variables value

The value could be (String, Number, List or C Pointer)

We need this function to quickly pass lists and C pointers to the Sub Ring Environment

Syntax:

.. code-block:: none

	ring_state_setvar(oState,cVariableName,Value)

Example:

.. code-block:: ring

	load "guilib.ring"

	myapp	= null
	win	= null

	func main
		myapp = new qApp {
			win = new qWidget() {
				setWindowTitle("Advanced Example on using ring_state_setvar()")
				move(100,100)
				resize(600,400)
				new qPushButton(win) {
					setText("Test")
					setClickEvent("Test()")
				}
				# We need this because using load 'guilib.ring' in the sub environment
				# Will create timers by Qt and closing the window will not be enough
				# To close the application
				oFilter = new qAllEvents(win)
				oFilter.setCloseEvent("myapp.quit()")
				win.installeventfilter(oFilter)
				show()
			}
			exec()
		}

	func test
		pState = ring_state_init()
		ring_state_runcode(pstate,"load 'guilib.ring'")
		ring_state_runcode(pState,"x = NULL")
		# Pass String
			ring_state_setvar(pState,"x","hello")
			ring_state_runcode(pState,"? x")
		# Pass Number
			ring_state_setvar(pState,"x",100)
			ring_state_runcode(pState,"? x")
		# Pass List
			ring_state_setvar(pState,"x",["one","two","three"])
			ring_state_runcode(pState,"? x")
		# Pass Object
		# We can't pass the Ring Object (win)
		# Because Objects store pointers to the Class Information
		# And the class is related to the Parent Ring Environment
		# And the sub Ring environment can't access it
		# But we can pass C pointers like win.pObject
			ring_state_setvar(pState,"x",win.pObject)
		# Now we create the object again but using the same C pointer
		# So we have access to the Same window in the parent Ring enviroment
			ring_state_runcode(pState,"
				new qWidget {
					pObject = x
					setwindowtitle('Message from the Sub Ring Environment')
				}
			")
		ring_state_delete(pState)



