2 single: Embedding Ring in Ring; Embedding Ring in Ring
8 In this chapter we will learn about embedding Ring in Ring programs and applications.
11 pair: Embedding Ring in Ring; Embedding Ring in Ring without sharing the State
13 Embedding Ring in Ring without sharing the State
14 ================================================
16 From Ring 1.0 we already have functions for embedding Ring in the C language. Also we
17 can execute Ring code inside Ring programs using the eval() function. In this release
18 we provide functions for embedding Ring in Ring programs without sharing the state.
22 (1) Quick integration for Ring programs and applications together without conflicts.
24 (2) Execute and run Ring code in safe environments that we can trace.
30 pState = ring_state_init()
31 ring_state_runcode(pState,"See 'Hello, World!'+nl")
32 ring_state_runcode(pState,"x = 10")
34 pState2 = ring_state_init()
35 ring_state_runcode(pState2,"See 'Hello, World!'+nl")
36 ring_state_runcode(pState2,"x = 20")
38 ring_state_runcode(pState,"see x +nl")
39 ring_state_runcode(pState2,"see x +nl")
41 v1 = ring_state_findvar(pState,"x")
42 v2 = ring_state_findvar(pState2,"x")
47 ring_state_delete(pState)
48 ring_state_delete(pState2)
62 pair: Embedding Ring in Ring; Serial Execution of Programs
64 Serial Execution of Programs
65 ============================
67 We can execute application after another application using ring_state_main()
73 chdir(exefolder()+"/../applications/formdesigner")
74 ring_state_main('formdesigner.ring')
75 chdir(exefolder()+"/../applications/cards")
76 ring_state_main('cards.ring')
79 pair: Embedding Ring in Ring; ring_state_setvar()
84 Using ring_state_setvar() we can set variables value
86 The value could be (String, Number, List or C Pointer)
88 We need this function to quickly pass lists and C pointers to the Sub Ring Environment
94 ring_state_setvar(oState,cVariableName,Value)
107 win = new qWidget() {
108 setWindowTitle("Advanced Example on using ring_state_setvar()")
111 new qPushButton(win) {
113 setClickEvent("Test()")
115 # We need this because using load 'guilib.ring' in
116 # the sub environment
117 # Will create timers by Qt and closing the window
118 # will not be enough to close the application
119 oFilter = new qAllEvents(win)
120 oFilter.setCloseEvent("myapp.quit()")
121 win.installeventfilter(oFilter)
128 pState = ring_state_init()
129 ring_state_runcode(pstate,"load 'guilib.ring'")
130 ring_state_runcode(pState,"x = NULL")
132 ring_state_setvar(pState,"x","hello")
133 ring_state_runcode(pState,"? x")
135 ring_state_setvar(pState,"x",100)
136 ring_state_runcode(pState,"? x")
138 ring_state_setvar(pState,"x",["one","two","three"])
139 ring_state_runcode(pState,"? x")
141 # We can't pass the Ring Object (win)
142 # Because Objects store pointers to the Class Information
143 # And the class is related to the Parent Ring Environment
144 # And the sub Ring environment can't access it
145 # But we can pass C pointers like win.pObject
146 ring_state_setvar(pState,"x",win.pObject)
147 # Now we create the object again but using the same C pointer
148 # So we have access to the Same window in the parent Ring enviroment
149 ring_state_runcode(pState,"
152 setwindowtitle('Message from the Sub Ring Environment')
155 ring_state_delete(pState)
159 pair: Embedding Ring in Ring; ring_state_new() and ring_state_mainfile()
161 ring_state_new() and ring_state_mainfile()
162 ==========================================
164 Using ring_state_new() and ring_state_mainfile() we can run Ring programs from Ring programs
166 But unlike ring_state_main(), Here we can control when to delete the Ring state!
168 This is important when we run GUI programs from GUI programs
170 Because they will share the GUI Library (RingQt), And In this case the caller will call
174 So the sub program, will not stop and will return to the Main program
176 Here deleting the State of the sub programs will lead to a problem when we run the sub program events
178 So keeping the state is important for sub GUI programs hosted in GUI programs.
188 win = new qWidget() {
189 setWindowTitle("Test ring_state_mainfile()")
190 resize(400,400) move(100,100)
191 btn = new qPushButton(Win) {
193 setclickevent("mytest()")
201 pState = ring_state_new()
202 ring_state_mainfile(pState,"runprogram.ring")
203 # Here we don't delete the state if we will run GUI application
204 # So we can run the GUI application events
205 // ring_state_delete(pState)
207 If you will use this feature, remember to update the previous example based on your application needs
209 So you can call ring_state_delete() at some point to avoid the memory leak!
212 pair: Embedding Ring in Ring; Runtime Errors when Embedding Ring in Ring
214 Runtime Errors when Embedding Ring in Ring
215 ==========================================
217 Starting from Ring 1.8
219 When embedding Ring in Ring, the error in the hosted environment will not close the host
227 pState = ring_state_init()
229 ring_state_runcode(pState," ? 'Let us try having an error' ? x")
231 ring_state_delete(pState)
241 Let us try having an error
243 Line 1 Error (R24) : Using uninitialized variable : x
244 in file Ring_EmbeddedCode
248 pair: Embedding Ring in Ring; ring_state_filetokens() function
250 ring_state_filetokens() function
251 ================================
253 Starting from Ring 1.12 we have the ring_state_filetokens() function
255 Using this function we can get all the tokens in the ring source code file.
259 C_FILENAME = "test_tokens.ring"
279 aKEYWORDS = ["IF","TO","OR","AND","NOT","FOR","NEW","FUNC",
280 "FROM","NEXT","LOAD","ELSE","SEE","WHILE","OK","CLASS","RETURN","BUT",
281 "END","GIVE","BYE","EXIT","TRY","CATCH","DONE","SWITCH","ON","OTHER","OFF",
282 "IN","LOOP","PACKAGE","IMPORT","PRIVATE","STEP","DO","AGAIN","CALL","ELSEIF",
283 "PUT","GET","CASE","DEF","ENDFUNC","ENDCLASS","ENDPACKAGE",
284 "CHANGERINGKEYWORD","CHANGERINGOPERATOR","LOADSYNTAX"]
286 pState = ring_state_new()
287 aList = ring_state_filetokens(pState,C_FILENAME)
289 ring_state_delete(pState)
291 func PrintTokens aList
295 ? Width("Keyword",C_WIDTH) + ": " + aKeywords[0+aToken[2]]
297 ? Width("Operator",C_WIDTH) + ": " + aToken[2]
299 ? Width("Literal",C_WIDTH) + ": " + aToken[2]
301 ? Width("Number",C_WIDTH) + ": " + aToken[2]
303 ? Width("Identifier",C_WIDTH) + ": " + aToken[2]
311 func Width cText,nWidth
312 return cText+copy(" ",nWidth-len(cText))
320 Literal : Hello, World!