diff --git a/samples/serversideviews_lua/lua4delphi/LICENSE b/samples/serversideviews_lua/lua4delphi/LICENSE new file mode 100644 index 00000000..8dada3ed --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/samples/serversideviews_lua/lua4delphi/Lua4DelphiGroup.groupproj b/samples/serversideviews_lua/lua4delphi/Lua4DelphiGroup.groupproj new file mode 100644 index 00000000..7c47aacd --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/Lua4DelphiGroup.groupproj @@ -0,0 +1,60 @@ + + + {162C2B63-ECD5-4626-8E5B-156604960725} + + + + + + + + + + + + + + Default.Personality.12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.DataSet.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.DataSet.pas new file mode 100644 index 00000000..92ef9107 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.DataSet.pas @@ -0,0 +1,129 @@ +unit LuaBind.CustomType.DataSet; + +interface + +uses + Data.DB, + LuaBind; + +type + TLuaDataSetExposerLibraries = class(TInterfacedObject, ILuaLibraryLoader) + + public + procedure Execute(ALuaEngine: TLuaEngine); + end; + +procedure ExposeDataSet(ALuaEngine: TLuaEngine; ADataSet: TDataSet; AVariableName: AnsiString); + +implementation + +uses LuaBind.Intf; + +function _dataset_eof(L: plua_state): Integer; cdecl; +var + ds: TDataSet; + s : ansistring; +begin + s := lua_typename(L, lua_type(L, - 1)); + assert(lua_islightuserdata(L, - 1)); + ds := TDataSet(lua_topointer(L, - 1)); + if ds.Eof then + lua_pushboolean(L, 1) + else + lua_pushboolean(L, 0); + Result := 1; +end; + +function _dataset_move_next(L: plua_state): Integer; cdecl; +var + ds: TDataSet; +begin + assert(lua_islightuserdata(L, - 1)); + ds := TDataSet(lua_topointer(L, - 1)); + ds.Next; + Result := 0; +end; + +function _dataset_field_by_name(L: plua_state): Integer; cdecl; +var + fieldname: AnsiString; + ds : TDataSet; + sdata : AnsiString; +begin + assert(lua_isstring(L, - 1) = 1); + assert(lua_islightuserdata(L, - 2)); + fieldname := lua_tostring(L, - 1); + lua_pop(L, 1); + ds := TDataSet(lua_topointer(L, - 1)); + lua_pop(L, 1); + + sdata := ds.FieldByName(String(fieldname)).AsAnsiString; + lua_pushstring(L, pansichar(sdata)); + Result := 1; +end; + +function _dataset_close(L: plua_state): Integer; cdecl; +var + ds: TDataSet; +begin + assert(lua_islightuserdata(L, - 1)); + ds := TDataSet(lua_topointer(L, - 1)); + ds.Close; + Result := 0; +end; + +function _dataset_first(L: plua_state): Integer; cdecl; +var + ds: TDataSet; +begin + assert(lua_islightuserdata(L, - 1)); + ds := TDataSet(lua_topointer(L, - 1)); + ds.First; + Result := 0; +end; + +function _dataset_is_open(L: plua_state): Integer; cdecl; +var + ds: TDataSet; + o : Integer; +begin + assert(lua_islightuserdata(L, - 1)); + ds := TDataSet(lua_topointer(L, - 1)); + if ds.State = dsInactive then + o := 0 + else + o := 1; + lua_pushboolean(L, o); + Result := 1; +end; + +function _dataset_open(L: plua_state): Integer; cdecl; +var + ds: TDataSet; +begin + assert(lua_islightuserdata(L, - 1)); + ds := TDataSet(lua_topointer(L, - 1)); + ds.Open; + Result := 0; +end; + +procedure ExposeDataSet(ALuaEngine: TLuaEngine; ADataSet: TDataSet; AVariableName: AnsiString); +begin + ALuaEngine.DeclareGlobalLightUserData(AVariableName, ADataSet); +end; + +{ TLuaDataSetExportlibraries } + +procedure TLuaDataSetExposerLibraries.Execute(ALuaEngine: TLuaEngine); +begin + ALuaEngine. + DeclareGlobalFunction('_dataset_eof', @_dataset_eof). + DeclareGlobalFunction('_dataset_move_next', @_dataset_move_next). + DeclareGlobalFunction('_dataset_field_by_name', @_dataset_field_by_name). + DeclareGlobalFunction('_dataset_first', @_dataset_first). + DeclareGlobalFunction('_dataset_is_open', @_dataset_is_open). + DeclareGlobalFunction('_dataset_open', @_dataset_open). + DeclareGlobalFunction('_dataset_close', @_dataset_close); +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.PODO.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.PODO.pas new file mode 100644 index 00000000..9e30569e --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.PODO.pas @@ -0,0 +1,285 @@ +unit LuaBind.CustomType.PODO; + +interface + +uses + LuaBind; + +type + TLuaDelphiObjectExposerLibraries = class(TInterfacedObject, ILuaLibraryLoader) + public + procedure Execute(ALuaEngine: TLuaEngine); + end; + +procedure ExposeDelphiObject(ALuaEngine: TLuaEngine; AObject: TObject; + AVariableName: AnsiString); + +implementation + +uses + LuaBind.Intf, + System.Rtti, + System.SysUtils, + System.TypInfo; + +function InvokeMethod(Obj: TObject; MethodName: AnsiString; params: TArray): TValue; +var + ctx : TRTTIContext; + _type: TRttiType; + _m : TRttiMethod; + _p : TRttiProperty; + _pars: TArray; + par : TRttiParameter; + i : Integer; +begin + ctx := TRTTIContext.Create; + try + _type := ctx.GetType(Obj.ClassInfo); + _m := _type.GetMethod(MethodName); + if _m = nil then + begin + _p := _type.GetProperty(MethodName); + if _p = nil then + raise Exception.CreateFmt('Method or property [%s] not found', [MethodName]); + Result := _p.GetValue(Obj); + end + else + begin + _pars := _m.GetParameters; + i := 0; + for par in _pars do + begin + if par.ParamType.TypeKind in [tkInteger, tkInt64] then + begin + if params[i].Kind in [tkFloat] then + params[i] := Trunc(params[i].AsExtended); + end; + end; + Result := _m.Invoke(Obj, params); + end; + finally + ctx.Free; + end; +end; + +procedure SetProperty(Obj: TObject; const PropertyName: string; + const Value: TValue); +var + Prop : TRttiProperty; + ARttiType: TRttiType; + ctx : TRTTIContext; +begin + ARttiType := ctx.GetType(Obj.ClassType); + if not Assigned(ARttiType) then + raise Exception.CreateFmt('Cannot get RTTI for type [%s]', + [ARttiType.ToString]); + Prop := ARttiType.GetProperty(PropertyName); + if not Assigned(Prop) then + raise Exception.CreateFmt('Cannot get RTTI for property [%s.%s]', + [ARttiType.ToString, PropertyName]); + if Prop.IsWritable then + begin + if Prop.PropertyType.TypeKind in [tkInteger, tkInt64] then + Prop.SetValue(Obj, Trunc(Value.AsExtended)) + else + Prop.SetValue(Obj, Value); + end + else + raise Exception.CreateFmt('Property is not writeable [%s.%s]', + [ARttiType.ToString, PropertyName]); +end; + +function _delphi_is_a_property(L: Plua_State): Integer; cdecl; +var + lvt : TLuaValueType; + PropertyName: string; + Obj : TObject; + propname : TValue; + ctx : TRTTIContext; + _rttitype : TRttiType; +begin + Result := 0; + try + assert(lua_isstring(L, - 1) = 1); + assert(lua_islightuserdata(L, - 2)); + PropertyName := TLuaValue.PopTValueFromStack(L).AsString; + Obj := TLuaValue.PopTValueFromStack(L).AsObject; + ctx := TRTTIContext.Create; + try + _rttitype := ctx.GetType(Obj.ClassType); + if Assigned(_rttitype.GetProperty(PropertyName)) then + TLuaUtils.PushTValue(L, true) + else + TLuaUtils.PushTValue(L, false); + finally + ctx.Free; + end; + Result := 1; + except + on E: Exception do + begin + lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message))); + lua_error(L); + end; + end; +end; + +// allows to create a delphi object using a parametersless constructor +function _delphi_create_object(L: Plua_State): Integer; cdecl; +var + ParCount : Integer; + _classname: string; + ctx : TRTTIContext; + _type : TRttiType; + Obj : TObject; + _m : TRttiMethod; + _mm : TRttiMethod; +begin + Result := 0; + try + ParCount := lua_gettop(L) - 1; + if ParCount > 0 then + raise ELuaConstructorException.Create('Constructor parameters are not supported'); + + // Create the object + _classname := TLuaValue.PopTValueFromStack(L).AsString; + _type := ctx.FindType(_classname); + if _type = nil then + raise ELuaException.Create('Cannot find type ' + _classname + + '. Is it a Fully Qualified Name?'); + + _m := nil; + for _mm in _type.AsInstance.GetDeclaredMethods do + if _mm.IsConstructor and (Length(_mm.GetParameters) = 0) then + begin + _m := _mm; + Break; + end; + + if Assigned(_m) then + Obj := _m.Invoke(_type.AsInstance.MetaclassType, []).AsObject + else + raise ELuaConstructorException.Create + ('Cannot find a suitable constructor for ' + _type.AsInstance.QualifiedName); + TLuaUtils.PushTValue(L, Obj); + Result := 1; + except + on E: Exception do + begin + lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message))); + lua_error(L); + end; + end; +end; + +function _delphi_set_property(L: Plua_State): Integer; cdecl; +var + Value : TValue; + PropertyName: AnsiString; + Obj : TObject; +begin + Result := 0; + try + assert(lua_isstring(L, - 2) = 1); + assert(lua_islightuserdata(L, - 3)); + Value := TLuaValue.PopTValueFromStack(L); + PropertyName := TLuaValue.PopTValueFromStack(L).AsString; + Obj := TLuaValue.PopTValueFromStack(L).AsObject; + SetProperty(Obj, PropertyName, Value); + Result := 0; + except + on E: Exception do + begin + lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message))); + lua_error(L); + end; + end; +end; + +function _delphi_call_method(L: Plua_State): Integer; cdecl; +var + s : AnsiString; + params : TArray; + maxindex : Integer; + i : Integer; + LuaValueType: TLuaValueType; + MethodName : AnsiString; + Obj : TObject; + v : TValue; +begin + Result := 0; + try + assert(lua_istable(L, - 1)); + assert(lua_isstring(L, - 2) = 1); + assert(lua_islightuserdata(L, - 3)); + + lua_getfield(L, - 1, 'maxindex'); + maxindex := lua_tointeger(L, - 1); + lua_pop(L, 1); + if maxindex > - 1 then + begin + SetLength(params, maxindex + 1); + for i := 0 to maxindex do + begin + s := '_' + IntToStr(i); + lua_getfield(L, - 1, PAnsiChar(s)); + LuaValueType := TLuaValue.GetLuaValueType(L, - 1); + params[i] := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1); + lua_pop(L, 1); + end; + end; + lua_pop(L, 1); // pop the table + + // read the method name + LuaValueType := TLuaValue.GetLuaValueType(L, - 1); + if LuaValueType <> lvtString then + raise ELuaException.Create('Bad error! Cannot find the method name'); + MethodName := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsString; + lua_pop(L, 1); // remove the methodname + + // read the pointer + LuaValueType := TLuaValue.GetLuaValueType(L, - 1); + if LuaValueType <> lvtLightUserData then + raise ELuaException.Create('Bad error! Cannot find the object ref'); + Obj := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsObject; + lua_pop(L, 1); // remove the lightuserdata + + v := InvokeMethod(Obj, MethodName, params); + if v.IsEmpty then + Result := 0 + else + begin + Result := 1; + TLuaUtils.PushTValue(L, v); + end; + except + on E: Exception do + begin + lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message))); + lua_error(L); + end; + end; +end; + +procedure ExposeDelphiObject(ALuaEngine: TLuaEngine; + AObject: + TObject; + AVariableName: + AnsiString); +begin + ALuaEngine.DeclareGlobalLightUserData(AVariableName, AObject); +end; + +{ TLuaDelphiObjectExposerLibraries } + +procedure TLuaDelphiObjectExposerLibraries.Execute(ALuaEngine: TLuaEngine); +begin + inherited; + ALuaEngine. + DeclareGlobalFunction('_delphi_call_method', @_delphi_call_method). + DeclareGlobalFunction('_delphi_create_object', @_delphi_create_object). + DeclareGlobalFunction('_delphi_is_a_property', @_delphi_is_a_property). + DeclareGlobalFunction('_delphi_set_property', @_delphi_set_property); +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.UserType.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.UserType.pas new file mode 100644 index 00000000..3a4b674d --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.CustomType.UserType.pas @@ -0,0 +1,95 @@ +unit LuaBind.CustomType.UserType; + +interface + +uses + LuaBind; + +type + TLuaMyTest = class(TInterfacedObject, ILuaLibraryLoader) + public + procedure Execute(ALuaEngine: TLuaEngine); + end; + +procedure ExposeMyTest(ALuaEngine: TLuaEngine; AObject: TObject; + AVariableName: AnsiString); + +implementation + +uses + LuaBind.Intf, + System.Classes; + +var + MyTest: TArray; + + { TLuaMyTest } + +type + PStringList = ^TStringlist; + +function _NewObject(L: Plua_State): Integer; cdecl; +var + psl: PStringList; +begin + if lua_gettop(L) <> 0 then + Exit(luaL_error(L, PAnsiChar('Got arguments expected no arguments'))); + psl := lua_newuserdata(L, SizeOf(PStringList)); + psl^ := TStringlist.Create; + lua_getglobal(L, PAnsiChar('TStringList')); + lua_setmetatable(L, - 2); + Result := 1; +end; + +function _TStringList_free(L: Plua_State): Integer; cdecl; +var + s: string; + p: PStringList; +begin + if (lua_gettop(L) <> 1) or (lua_isuserdata(L, - 1) = 0) then + Exit(luaL_error(L, PAnsiChar('No params allowed or no valid userdata'))); + p := PStringList(lua_touserdata(L, - 1)); + lua_pop(L, 1); + p^.Free; + p^ := nil; + Result := 0; +end; + +function _TStringList_add(L: Plua_State): Integer; cdecl; +var + s: string; + p: PStringList; +begin + if lua_gettop(L) <> 2 then + Exit(luaL_error(L, PAnsiChar('Wrong number of parameters: 2 expected'))); + s := TLuaValue.PopTValueFromStack(L).AsString; + p := PStringList(lua_touserdata(L, - 1)); + lua_pop(L, 1); + p^.Add(s); + Result := 0; +end; + +procedure TLuaMyTest.Execute(ALuaEngine: TLuaEngine); +begin + SetLength(MyTest, 4); + MyTest[0].name := PAnsiChar('new'); + MyTest[0].func := @_NewObject; + MyTest[1].name := PAnsiChar('add'); + MyTest[1].func := @_TStringList_add; + MyTest[2].name := PAnsiChar('__gc'); + MyTest[2].func := @_TStringList_free; + MyTest[3].name := nil; + MyTest[3].func := nil; + + luaL_register(ALuaEngine.GetRawLuaState, 'TStringList', @MyTest[0]); + lua_pushvalue(ALuaEngine.GetRawLuaState, - 1); + lua_setfield(ALuaEngine.GetRawLuaState, - 2, '__index'); +end; + +procedure ExposeMyTest(ALuaEngine: TLuaEngine; AObject: TObject; + AVariableName: AnsiString); +begin + +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.DelphiObjects.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.DelphiObjects.pas new file mode 100644 index 00000000..35d61dd2 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.DelphiObjects.pas @@ -0,0 +1,131 @@ +unit LuaBind.DelphiObjects; + +interface + +uses + LuaBind.Intf; + +function _delphi_call_method(const L: Plua_State): Integer; cdecl; + +implementation + +uses + System.Rtti, + LuaBind, + System.SysUtils, + System.TypInfo; + +function InvokeMethod(Obj: TObject; MethodName: AnsiString; params: TArray): TValue; +var + ctx: TRTTIContext; + _type: TRttiType; + _m: TRttiMethod; + _p: TRttiProperty; + _pars: TArray; + par: TRttiParameter; + i: Integer; + LMethodName: String; +begin + LMethodName := String(MethodName); + ctx := TRTTIContext.Create; + try + _type := ctx.GetType(Obj.ClassInfo); + _m := _type.GetMethod(LMethodName); + if _m = nil then + begin + _p := _type.GetProperty(LMethodName); + if _p = nil then + raise Exception.CreateFmt('Method or property [%s] not found', [LMethodName]); + Result := _p.GetValue(Obj); + end + else + begin + _pars := _m.GetParameters; + i := 0; + for par in _pars do + begin + if par.ParamType.TypeKind in [tkInteger, tkInt64] then + begin + if params[i].Kind in [tkFloat] then + params[i] := Trunc(params[i].AsExtended); + end; + end; + Result := _m.Invoke(Obj, params); + end; + finally + ctx.Free; + end; +end; + +function _delphi_call_method(const L: Plua_State): Integer; cdecl; +var + s: AnsiString; + params: TArray; + maxindex: Integer; + i: Integer; + LuaValueType: TLuaValueType; + MethodName: AnsiString; + Obj: TObject; + v: TValue; +begin + Result := 0; + try + Result := lua_gettop(L); + assert(lua_istable(L, 1)); + assert(lua_isstring(L, 2) = 1); + + MethodName := lua_tostring(L, 2); + + // assert(lua_islightuserdata(L, - 3)); + + // lua_getfield(L, - 1, 'maxindex'); + // maxindex := lua_tointeger(L, - 1); //decomment this?7 + maxindex := 0; { TODO -oOwner -cGeneral : this method is in alpha stage } + + lua_pop(L, 1); + if maxindex > - 1 then + begin + SetLength(params, maxindex + 1); + for i := 0 to maxindex do + begin + s := '_' + AnsiString(IntToStr(i)); + lua_getfield(L, - 1, PAnsiChar(s)); + LuaValueType := TLuaValue.GetLuaValueType(L, - 1); + params[i] := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1); + lua_pop(L, 1); + end; + end; + lua_pop(L, 1); // pop the table + + // read the method name + LuaValueType := TLuaValue.GetLuaValueType(L, - 1); + if LuaValueType <> lvtString then + raise ELuaException.Create('Bad error! Cannot find the method name'); + MethodName := AnsiString(TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsString); + lua_pop(L, 1); // remove the methodname + + // read the pointer + LuaValueType := TLuaValue.GetLuaValueType(L, - 1); + if LuaValueType <> lvtLightUserData then + raise ELuaException.Create('Bad error! Cannot find the object ref'); + Obj := TLuaValue.GetTValueFromLuaValueType(LuaValueType, L, - 1).AsObject; + lua_pop(L, 1); // remove the lightuserdata + + v := InvokeMethod(Obj, MethodName, params); + if v.IsEmpty then + Result := 0 + else + begin + Result := 1; + TLuaUtils.PushTValue(L, v); + end; + except + on E: Exception do + begin + lua_pushstring(L, PAnsiChar(UTF8Encode(E.ClassName + ' ' + E.Message))); + lua_error(L); + end; + end; +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.Filters.Text.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.Filters.Text.pas new file mode 100644 index 00000000..8d65fc1a --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.Filters.Text.pas @@ -0,0 +1,388 @@ +{$WARNINGS OFF} +unit LuaBind.Filters.Text; + +interface + +uses + System.SysUtils; + +type + TLuaEmbeddedTextFilter = class + private + FTemplateCode: string; + FLuaCode: string; + FCurrCharIndex: int64; + FOutputStringBuilder: TStringBuilder; + FCurrChar: Char; + FOutputFunction: string; + procedure SetLuaCode(const Value: string); + procedure SetTemplateCode(const Value: string); + procedure NextChar; + function LookAhead(Offset: Integer): Char; + procedure PushToOutput(const AChar: Char); + procedure SetOutputFunction(const Value: string); + + public + constructor Create; + procedure Execute; + property TemplateCode: string read FTemplateCode write SetTemplateCode; + property LuaCode: string read FLuaCode write SetLuaCode; + property OutputFunction: string read FOutputFunction write SetOutputFunction; + // helpers + class function ExecuteWithResult(eLuaScript: AnsiString; const ParamNames: array of string; + const ParamValues: array of string): string; + end; + +implementation + +uses + LuaBind.Intf, + System.Classes, + LuaBind; + +threadvar _OutputBuffer: TStringBuilder; + +function __lua_stream_out(L: Plua_State): Integer; cdecl; +var + s: string; + o: TObject; + stream: TStreamWriter; +begin + if lua_gettop(L) <> 2 then + begin + luaL_error(L, PAnsiChar('Wrong parameters number')); + Exit(0); + end; + + if lua_isstring(L, - 1) = 1 then + begin + s := lua_tostring(L, - 1); + lua_pop(L, 1); + end + else + begin + luaL_error(L, PAnsiChar('Type mismatch, expected String')); + Exit(0); + end; + + if lua_islightuserdata(L, - 1) then + begin + o := TObject(lua_topointer(L, - 1)); + lua_pop(L, 1); + end + else + begin + luaL_error(L, PAnsiChar('Type mismatch, expected LightUserData')); + Exit(0); + end; + + stream := o as TStreamWriter; + stream.Write(s); + Result := 0; +end; + +{ TLuaEmbeddedTextFilter } + +constructor TLuaEmbeddedTextFilter.Create; +begin + inherited; + FOutputFunction := 'response:out'; +end; + +procedure TLuaEmbeddedTextFilter.Execute; +var + StartCode: Boolean; + State: Integer; +const + PARSER_VERBATIM_TEXT = $8000; + PARSER_VERBATIM_CODE = PARSER_VERBATIM_TEXT + 1; + PARSER_VERBATIM_EXPRESSION = PARSER_VERBATIM_CODE + 1; + PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED = PARSER_VERBATIM_EXPRESSION + 1; + PARSER_VERBATIM_CODE_STRING_DOUBLE_QUOTED = PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED + 1; +begin + FCurrCharIndex := 0; + State := PARSER_VERBATIM_TEXT; + + NextChar; + FOutputStringBuilder := TStringBuilder.Create; + try + StartCode := True; + while FCurrChar <> #0 do + begin + case State of + PARSER_VERBATIM_TEXT: + begin + if FCurrChar = '<' then + begin + if (LookAhead(1) = '?') and (LookAhead(2) = 'l') and (LookAhead(3) = 'u') and + (LookAhead(4) = 'a') then + begin + NextChar; // ? + NextChar; // l + NextChar; // u + NextChar; // a + NextChar; // _ + if not StartCode then + FOutputStringBuilder.Append(']]'); + StartCode := False; + + if FCurrChar = '=' then // expression + begin + State := PARSER_VERBATIM_EXPRESSION; + FOutputStringBuilder.Append(FOutputFunction + '('); + NextChar; + end + else + State := PARSER_VERBATIM_CODE; + end + else + begin + if StartCode then + begin + StartCode := False; + FOutputStringBuilder.Append(FOutputFunction + ' [[' + sLineBreak); + end; + PushToOutput('<'); + NextChar; + end; + end + else // FCurrChar <> '<' + begin + if StartCode then + begin + StartCode := False; + FOutputStringBuilder.Append(FOutputFunction + ' [[' + sLineBreak); + end; + PushToOutput(FCurrChar); + NextChar; + end; + end; + + PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED: + begin + if FCurrChar = '''' then + begin + State := PARSER_VERBATIM_CODE; + PushToOutput(''''); + NextChar; + end + else if (FCurrChar = '\') and (LookAhead(1) = '''') then + begin + PushToOutput('\'); + PushToOutput(''''); + NextChar; + NextChar; + end + else + begin + PushToOutput(FCurrChar); + NextChar; + end; + end; + + PARSER_VERBATIM_CODE_STRING_DOUBLE_QUOTED: + begin + if FCurrChar = '"' then + begin + State := PARSER_VERBATIM_CODE; + PushToOutput('"'); + NextChar; + end + else if (FCurrChar = '\') and (LookAhead(1) = '"') then + begin + PushToOutput('\'); + PushToOutput('"'); + NextChar; + NextChar; + end + else + begin + PushToOutput(FCurrChar); + NextChar; + end; + end; + + PARSER_VERBATIM_CODE: + begin + if FCurrChar = '''' then + begin + State := PARSER_VERBATIM_CODE_STRING_SINGLE_QUOTED; + PushToOutput(''''); + NextChar; + end + else if FCurrChar = '"' then + begin + State := PARSER_VERBATIM_CODE_STRING_DOUBLE_QUOTED; + PushToOutput('"'); + NextChar; + end + else if FCurrChar = '?' then + begin + if (LookAhead(1) = '>') then + begin + NextChar; // > + NextChar; // _ + FOutputStringBuilder.Append(sLineBreak + FOutputFunction + ' [[' + sLineBreak); + State := PARSER_VERBATIM_TEXT; + end + else + begin + PushToOutput('?'); + NextChar; + end; + end + else // FCurrChar <> '?' + begin + PushToOutput(FCurrChar); + NextChar; + end; + end; // PARSER_VERBATIM_CODE + + PARSER_VERBATIM_EXPRESSION: + begin + if FCurrChar = '?' then + begin + if (LookAhead(1) = '>') then + begin + NextChar; // > + NextChar; // _ + FOutputStringBuilder.Append(')'); + FOutputStringBuilder.Append(sLineBreak + FOutputFunction + ' [[' + sLineBreak); + State := PARSER_VERBATIM_TEXT; + end + else + begin + PushToOutput('?'); + NextChar; + end; + end + else // FCurrChar <> '?' + begin + PushToOutput(FCurrChar); + NextChar; + end; + end; + end; // case + end; // while + + if (State = PARSER_VERBATIM_TEXT) and (not StartCode) then + FOutputStringBuilder.Append(']]') + else if not StartCode then + raise ELuaFilterException.Create('Expected closing Lua tag'); + + FLuaCode := FOutputStringBuilder.ToString; + finally + FOutputStringBuilder.Free; + end; +end; + +function __lua_out(L: Plua_State): Integer; cdecl; +var + s: string; +begin + if lua_gettop(L) <> 1 then + begin + luaL_error(L, PAnsiChar('Wrong parameters number')); + Exit(0); + end; + + if lua_isstring(L, - 1) = 1 then + begin + s := lua_tostring(L, - 1); + lua_pop(L, 1); + end + else + begin + luaL_error(L, PAnsiChar('Type mismatch, expected String')); + Exit(0); + end; + _OutputBuffer.Append(s); + Result := 0; +end; + +class function TLuaEmbeddedTextFilter.ExecuteWithResult(eLuaScript: AnsiString; + const ParamNames, ParamValues: array of string): string; +var + LuaFilter: TLuaEmbeddedTextFilter; + L: TLuaEngine; + I: Integer; + + function GetOutputBuffer: TStringBuilder; + begin + Result := _OutputBuffer; + end; + +begin + if Length(ParamNames) <> Length(ParamValues) then + raise ELuaRuntimeException.Create('Number of params names and param values is not equals'); + + LuaFilter := TLuaEmbeddedTextFilter.Create; + try + LuaFilter.OutputFunction := '_out'; + LuaFilter.TemplateCode := eLuaScript; + LuaFilter.Execute; + + _OutputBuffer := TStringBuilder.Create; + try + L := TLuaEngine.Create; + try + for I := 0 to Length(ParamNames) - 1 do + L.DeclareGlobalString(ParamNames[I], ParamValues[I]); + L.DeclareGlobalFunction('_out', @__lua_out); + L.LoadScript(LuaFilter.LuaCode); + L.Execute; + Result := _OutputBuffer.ToString; + finally + L.Free; + end; + finally + FreeAndNil(_OutputBuffer); + end; + finally + LuaFilter.Free; + end; +end; + +function TLuaEmbeddedTextFilter.LookAhead(Offset: Integer): Char; +begin + if FCurrCharIndex + Offset <= Length(FTemplateCode) then + Result := FTemplateCode[FCurrCharIndex + Offset] + else + Result := #0; +end; + +procedure TLuaEmbeddedTextFilter.NextChar; +begin + if FCurrCharIndex = Length(FTemplateCode) then + begin + FCurrCharIndex := - 1; + FCurrChar := #0; + end + else + begin + FCurrCharIndex := FCurrCharIndex + 1; + FCurrChar := FTemplateCode[FCurrCharIndex]; + end; +end; + +procedure TLuaEmbeddedTextFilter.PushToOutput(const AChar: Char); +begin + FOutputStringBuilder.Append(AChar); +end; + +procedure TLuaEmbeddedTextFilter.SetLuaCode(const Value: string); +begin + FLuaCode := Value; +end; + +procedure TLuaEmbeddedTextFilter.SetOutputFunction(const Value: string); +begin + FOutputFunction := Value; +end; + +procedure TLuaEmbeddedTextFilter.SetTemplateCode(const Value: string); +begin + FTemplateCode := Value; +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.Intf.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.Intf.pas new file mode 100644 index 00000000..99dea15c --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.Intf.pas @@ -0,0 +1,1221 @@ +(* ***************************************************************************** + * Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ***************************************************************************** *) + +{$IFDEF FPC} +{$MODE OBJFPC}{$M+} +{$DEFINE HAVEINLINE} +{$ENDIF} + +unit LuaBind.Intf; + +interface + +uses classes; + +type + size_t = Cardinal; + Psize_t = ^size_t; + + {$IFNDEF FPC} + + PtrInt = Integer; + + {$ENDIF} + + +const + + {$IFDEF UNIX} + + LUA_LIB = 'liblua5.1.so'; + + {$ELSE} + + LUA_LIB = 'lua5.1.dll'; + + {$ENDIF} + + +const + LUA_IDSIZE = 60; + LUAL_BUFFERSIZE = 512; + + (* + ** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ + ** Lua - An Extensible Extension Language + ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) + ** See Copyright Notice at the end of this file + *) + + + // #include "luaconf.h" + +const + LUA_VERSION = 'Lua 5.1'; + LUA_RELEASE = 'Lua 5.1.4'; + LUA_VERSION_NUM = 501; + LUA_COPYRIGHT = 'Copyright (C) 1994-2008 Lua.org, PUC-Rio'; + LUA_AUTHORS = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes'; + + (* mark for precompiled code (`Lua') *) + LUA_SIGNATURE = #33'Lua'; + + (* option for multiple returns in `lua_pcall' and `lua_call' *) + LUA_MULTRET = - 1; + + (* + ** pseudo-indices + *) + LUA_REGISTRYINDEX = - 10000; + LUA_ENVIRONINDEX = - 10001; + LUA_GLOBALSINDEX = - 10002; +function lua_upvalueindex(i: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +(* thread status; 0 is OK *) +const + LUA_YIELD_ = 1; + LUA_ERRRUN = 2; + LUA_ERRSYNTAX = 3; + LUA_ERRMEM = 4; + LUA_ERRERR = 5; + +type + Plua_State = ^lua_State; + + lua_State = record + + end; + + lua_CFunction = function(L: Plua_State): Integer; cdecl; + + (* + ** functions that read/write blocks when loading/dumping Lua chunks + *) + lua_Reader = function(L: Plua_State; ud: Pointer; sz: Psize_t): PAnsiChar; cdecl; + lua_Writer = function(L: Plua_State; const p: Pointer; sz: Psize_t; ud: Pointer): Integer; cdecl; + + (* + ** prototype for memory-allocation functions + *) + lua_Alloc = function(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl; + + (* + ** basic types + *) +const + LUA_TNONE = - 1; + + LUA_TNIL = 0; + LUA_TBOOLEAN = 1; + LUA_TLIGHTUSERDATA = 2; + LUA_TNUMBER = 3; + LUA_TSTRING = 4; + LUA_TTABLE = 5; + LUA_TFUNCTION = 6; + LUA_TUSERDATA = 7; + LUA_TTHREAD = 8; + + (* minimum Lua stack available to a C function *) + LUA_MINSTACK = 20; + + (* + ** generic extra include file + *) + // #if defined(LUA_USER_H) + // #include LUA_USER_H + // #endif + +type + (* type of numbers in Lua *) + lua_Number = Double; // LUA_NUMBER + + (* type for integer functions *) + lua_Integer = PtrInt; // LUA_INTEGER + + (* + ** state manipulation + *) +function lua_newstate(f: lua_Alloc; ud: Pointer): Plua_State; cdecl; + external LUA_LIB name 'lua_newstate'; +procedure lua_close(L: Plua_State); cdecl; external LUA_LIB name 'lua_close'; +function lua_newthread(L: Plua_State): Plua_State; cdecl; external LUA_LIB name 'lua_newthread'; + +function lua_atpanic(L: Plua_State; panicf: lua_CFunction): lua_CFunction; cdecl; + external LUA_LIB name 'lua_atpanic'; + +(* + ** basic stack manipulation +*) +function lua_gettop(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_gettop'; +procedure lua_settop(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_settop'; +procedure lua_pushvalue(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_pushvalue'; +procedure lua_remove(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_remove'; +procedure lua_insert(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_insert'; +procedure lua_replace(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_replace'; +function lua_checkstack(L: Plua_State; sz: Integer): Integer; cdecl; + external LUA_LIB name 'lua_checkstack'; + +procedure lua_xmove(from: Plua_State; to_: Plua_State; n: Integer); cdecl; + external LUA_LIB name 'lua_xmove'; + +(* + ** access functions (stack -> C) +*) + +function lua_isnumber(L: Plua_State; idx: Integer): Integer; cdecl; + external LUA_LIB name 'lua_isnumber'; +function lua_isstring(L: Plua_State; idx: Integer): Integer; cdecl; + external LUA_LIB name 'lua_isstring'; +function lua_iscfunction(L: Plua_State; idx: Integer): Integer; cdecl; + external LUA_LIB name 'lua_iscfunction'; +function lua_isuserdata(L: Plua_State; idx: Integer): Integer; cdecl; + external LUA_LIB name 'lua_isuserdata'; +function lua_type(L: Plua_State; idx: Integer): Integer; cdecl; external LUA_LIB name 'lua_type'; +function lua_typename(L: Plua_State; tp: Integer): PAnsiChar; cdecl; + external LUA_LIB name 'lua_typename'; + +function lua_equal(L: Plua_State; idx1: Integer; idx2: Integer): Integer; cdecl; + external LUA_LIB name 'lua_equal'; +function lua_rawequal(L: Plua_State; idx1: Integer; idx2: Integer): Integer; cdecl; + external LUA_LIB name 'lua_rawequal'; +function lua_lessthan(L: Plua_State; idx1: Integer; idx2: Integer): Integer; cdecl; + external LUA_LIB name 'lua_lessthan'; + +function lua_tonumber(L: Plua_State; idx: Integer): lua_Number; cdecl; + external LUA_LIB name 'lua_tonumber'; +function lua_tointeger(L: Plua_State; idx: Integer): lua_Integer; cdecl; + external LUA_LIB name 'lua_tointeger'; +function lua_toboolean(L: Plua_State; idx: Integer): Integer; cdecl; + external LUA_LIB name 'lua_toboolean'; +function lua_tolstring(L: Plua_State; idx: Integer; len: Psize_t): PAnsiChar; cdecl; + external LUA_LIB name 'lua_tolstring'; +function lua_objlen(L: Plua_State; idx: Integer): size_t; cdecl; external LUA_LIB name 'lua_objlen'; +function lua_tocfunction(L: Plua_State; idx: Integer): lua_CFunction; cdecl; + external LUA_LIB name 'lua_tocfunction'; +function lua_touserdata(L: Plua_State; idx: Integer): Pointer; cdecl; + external LUA_LIB name 'lua_touserdata'; +function lua_tothread(L: Plua_State; idx: Integer): Plua_State; cdecl; + external LUA_LIB name 'lua_tothread'; +function lua_topointer(L: Plua_State; idx: Integer): Pointer; cdecl; + external LUA_LIB name 'lua_topointer'; + +(* + ** push functions (C -> stack) +*) +procedure lua_pushnil(L: Plua_State); cdecl; external LUA_LIB name 'lua_pushnil'; +procedure lua_pushnumber(L: Plua_State; n: lua_Number); cdecl; + external LUA_LIB name 'lua_pushnumber'; +procedure lua_pushinteger(L: Plua_State; n: lua_Integer); cdecl; + external LUA_LIB name 'lua_pushinteger'; +procedure lua_pushlstring(L: Plua_State; const s: PAnsiChar; len: size_t); cdecl; + external LUA_LIB name 'lua_pushlstring'; +procedure lua_pushstring(L: Plua_State; const s: PAnsiChar); cdecl; + external LUA_LIB name 'lua_pushstring'; +function lua_pushvfstring(L: Plua_State; const fmt: PAnsiChar): PAnsiChar; varargs; cdecl; + external LUA_LIB name 'lua_pushvfstring'; +function lua_pushfstring(L: Plua_State; const fmt: PAnsiChar): PAnsiChar; varargs; cdecl; + external LUA_LIB name 'lua_pushfstring'; +procedure lua_pushcclosure(L: Plua_State; fn: lua_CFunction; n: Integer); cdecl; + external LUA_LIB name 'lua_pushcclosure'; +procedure lua_pushboolean(L: Plua_State; b: Integer); cdecl; + external LUA_LIB name 'lua_pushboolean'; +procedure lua_pushlightuserdata(L: Plua_State; p: Pointer); cdecl; + external LUA_LIB name 'lua_pushlightuserdata'; +function lua_pushthread(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_pushthread'; + +(* + ** get functions (Lua -> stack) +*) +procedure lua_gettable(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_gettable'; +procedure lua_getfield(L: Plua_State; idx: Integer; const k: PAnsiChar); cdecl; + external LUA_LIB name 'lua_getfield'; +procedure lua_rawget(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_rawget'; +procedure lua_rawgeti(L: Plua_State; idx: Integer; n: Integer); cdecl; + external LUA_LIB name 'lua_rawgeti'; +procedure lua_createtable(L: Plua_State; narr: Integer; nrec: Integer); cdecl; + external LUA_LIB name 'lua_createtable'; +function lua_newuserdata(L: Plua_State; sz: size_t): Pointer; cdecl; + external LUA_LIB name 'lua_newuserdata'; +function lua_getmetatable(L: Plua_State; objindex: Integer): Integer; cdecl; + external LUA_LIB name 'lua_getmetatable'; +procedure lua_getfenv(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_getfenv'; + +(* + ** set functions (stack -> Lua) +*) +procedure lua_settable(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_settable'; +procedure lua_setfield(L: Plua_State; idx: Integer; const k: PAnsiChar); cdecl; + external LUA_LIB name 'lua_setfield'; +procedure lua_rawset(L: Plua_State; idx: Integer); cdecl; external LUA_LIB name 'lua_rawset'; +procedure lua_rawseti(L: Plua_State; idx: Integer; n: Integer); cdecl; + external LUA_LIB name 'lua_rawseti'; +function lua_setmetatable(L: Plua_State; objindex: Integer): Integer; cdecl; + external LUA_LIB name 'lua_setmetatable'; +function lua_setfenv(L: Plua_State; idx: Integer): Integer; cdecl; + external LUA_LIB name 'lua_setfenv'; + +(* + ** `load' and `call' functions (load and run Lua code) +*) +procedure lua_call(L: Plua_State; nargs: Integer; nresults: Integer); cdecl; + external LUA_LIB name 'lua_call'; +function lua_pcall(L: Plua_State; nargs: Integer; nresults: Integer; errfunc: Integer): Integer; + cdecl; external LUA_LIB name 'lua_pcall'; +function lua_cpcall(L: Plua_State; func: lua_CFunction; ud: Pointer): Integer; cdecl; + external LUA_LIB name 'lua_cpcall'; +function lua_load(L: Plua_State; reader: lua_Reader; dt: Pointer; const chunkname: PAnsiChar) + : Integer; cdecl; external LUA_LIB name 'lua_load'; + +function lua_dump(L: Plua_State; writer: lua_Writer; data: Pointer): Integer; cdecl; + external LUA_LIB name 'lua_dump'; + +(* + ** coroutine functions +*) +function lua_yield(L: Plua_State; nresults: Integer): Integer; cdecl; + external LUA_LIB name 'lua_yield'; +function lua_resume(L: Plua_State; narg: Integer): Integer; cdecl; + external LUA_LIB name 'lua_resume'; +function lua_status(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_status'; + +(* + ** garbage-collection function and options +*) + +const + LUA_GCSTOP = 0; + LUA_GCRESTART = 1; + LUA_GCCOLLECT = 2; + LUA_GCCOUNT = 3; + LUA_GCCOUNTB = 4; + LUA_GCSTEP = 5; + LUA_GCSETPAUSE = 6; + LUA_GCSETSTEPMUL = 7; + +function lua_gc(L: Plua_State; what: Integer; data: Integer): Integer; cdecl; + external LUA_LIB name 'lua_gc'; + +(* + ** miscellaneous functions +*) + +function lua_error(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_error'; + +function lua_next(L: Plua_State; idx: Integer): Integer; cdecl; external LUA_LIB name 'lua_next'; + +procedure lua_concat(L: Plua_State; n: Integer); cdecl; external LUA_LIB name 'lua_concat'; + +function lua_getallocf(L: Plua_State; var ud: Pointer): lua_Alloc; cdecl; + external LUA_LIB name 'lua_getallocf'; +procedure lua_setallocf(L: Plua_State; f: lua_Alloc; ud: Pointer); cdecl; + external LUA_LIB name 'lua_setallocf '; + +(* + ** =============================================================== + ** some useful macros + ** =============================================================== +*) + +procedure lua_pop(L: Plua_State; n: Integer); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +procedure lua_newtable(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +procedure lua_register(L: Plua_State; n: PAnsiChar; f: lua_CFunction); {$IFDEF HAVEINLINE}inline; + +{$ENDIF} + +procedure lua_pushcfunction(L: Plua_State; f: lua_CFunction); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_strlen(L: Plua_State; i: Integer): size_t; cdecl; external LUA_LIB name 'lua_objlen'; +function lua_isfunction(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_istable(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_islightuserdata(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; + +{$ENDIF} + +function lua_isnil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_isboolean(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_isthread(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_isnone(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_isnoneornil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +procedure lua_pushliteral(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +procedure lua_setglobal(L: Plua_State; s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +procedure lua_getglobal(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_tostring(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +(* + ** compatibility macros and functions +*) + +function lua_open: Plua_State; cdecl; external LUA_LIB name 'luaL_newstate'; +procedure lua_getregistry(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_getgccount(L: Plua_State): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +type + lua_Chunkreader = type lua_Reader; + lua_Chunkwriter = type lua_Writer; + + (* hack *) +procedure lua_setlevel(from: Plua_State; to_: Plua_State); cdecl; + external LUA_LIB name 'lua_setlevel '; + +(* + ** {====================================================================== + ** Debug API + ** ======================================================================= +*) + +(* + ** Event codes +*) +const + LUA_HOOKCALL = 0; + LUA_HOOKRET = 1; + LUA_HOOKLINE = 2; + LUA_HOOKCOUNT = 3; + LUA_HOOKTAILRET = 4; + + (* + ** Event masks + *) + LUA_MASKCALL = (1 shl LUA_HOOKCALL); + LUA_MASKRET = (1 shl LUA_HOOKRET); + LUA_MASKLINE = (1 shl LUA_HOOKLINE); + LUA_MASKCOUNT = (1 shl LUA_HOOKCOUNT); + LUA_MASKTAILRET = (1 shl LUA_HOOKTAILRET); + +type + Plua_Debug = ^lua_Debug; + + lua_Debug = record + event: Integer; + name: PAnsiChar; (* (n) *) + namewhat: PAnsiChar; (* (n) `global', `local', `field', `method' *) + what: PAnsiChar; (* (S) `Lua', `C', `main', `tail' *) + source: PAnsiChar; (* (S) *) + currentline: Integer; (* (l) *) + nups: Integer; (* (u) number of upvalues *) + linedefined: Integer; (* (S) *) + lastlinedefined: Integer; (* (S) *) + short_src: array [0 .. LUA_IDSIZE - 1] of AnsiChar; (* (S) *) + (* private part *) + i_ci: Integer; (* active function *) + end; (* activation record *) + + (* Functions to be called by the debuger in specific events *) + lua_Hook = procedure(L: Plua_State; ar: Plua_Debug); cdecl; + +function lua_getstack(L: Plua_State; level: Integer; ar: Plua_Debug): Integer; cdecl; + external LUA_LIB name 'lua_getstack'; +function lua_getinfo(L: Plua_State; const what: PAnsiChar; ar: Plua_Debug): Integer; cdecl; + external LUA_LIB name 'lua_getinfo'; +function lua_getlocal(L: Plua_State; const ar: Plua_Debug; n: Integer): PAnsiChar; cdecl; + external LUA_LIB name 'lua_getlocal'; +function lua_setlocal(L: Plua_State; const ar: Plua_Debug; n: Integer): PAnsiChar; cdecl; + external LUA_LIB name 'lua_setlocal'; +function lua_getupvalue(L: Plua_State; funcindex: Integer; n: Integer): PAnsiChar; cdecl; + external LUA_LIB name 'lua_getupvalue'; +function lua_setupvalue(L: Plua_State; funcindex: Integer; n: Integer): PAnsiChar; cdecl; + external LUA_LIB name 'lua_setupvalue'; + +function lua_sethook(L: Plua_State; func: lua_Hook; mask: Integer; count: Integer): Integer; cdecl; + external LUA_LIB name 'lua_sethook'; +function lua_gethook(L: Plua_State): lua_Hook; cdecl; external LUA_LIB name 'lua_gethook'; +function lua_gethookmask(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_gethookmask'; +function lua_gethookcount(L: Plua_State): Integer; cdecl; external LUA_LIB name 'lua_gethookcount'; + +(* }====================================================================== *) + +(* + ** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ + ** Auxiliary functions for building Lua libraries + ** See Copyright Notice in lua.h +*) + +// #if defined(LUA_COMPAT_GETN) +// LUALIB_API int (luaL_getn) (lua_State *L, int t); +// LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +// #else +function luaL_getn(L: Plua_State; idx: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} +// #define luaL_setn(L,i,j) ((void)0) (* no op! *) +// #endif + +// #if defined(LUA_COMPAT_OPENLIB) +// #define luaI_openlib luaL_openlib +// #endif + +(* extra error code for `luaL_load' *) +const + LUA_ERRFILE = LUA_ERRERR + 1; + +type + PluaL_Reg = ^luaL_Reg; + + luaL_Reg = record + name: PAnsiChar; + func: lua_CFunction; + end; + +procedure luaI_openlib(L: Plua_State; const libname: PAnsiChar; const lr: PluaL_Reg; nup: Integer); + cdecl; external LUA_LIB name 'luaI_openlib'; +procedure luaL_register(L: Plua_State; const libname: PAnsiChar; const lr: PluaL_Reg); cdecl; + external LUA_LIB name 'luaL_register'; +function luaL_getmetafield(L: Plua_State; obj: Integer; const e: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_getmetafield'; +function luaL_callmeta(L: Plua_State; obj: Integer; const e: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_callmeta'; +function luaL_typerror(L: Plua_State; narg: Integer; const tname: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_typerror'; +function luaL_argerror(L: Plua_State; numarg: Integer; const extramsg: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_argerror'; +function luaL_checklstring(L: Plua_State; numarg: Integer; len: Psize_t): PAnsiChar; cdecl; + external LUA_LIB name 'luaL_checklstring'; +function luaL_optlstring(L: Plua_State; numarg: Integer; const def: PAnsiChar; len: Psize_t) + : PAnsiChar; cdecl; external LUA_LIB name 'luaL_optlstring'; +function luaL_checknumber(L: Plua_State; numarg: Integer): lua_Number; cdecl; + external LUA_LIB name 'luaL_checknumber'; +function luaL_optnumber(L: Plua_State; narg: Integer; def: lua_Number): lua_Number; cdecl; + external LUA_LIB name 'luaL_optnumber'; +function luaL_checkinteger(L: Plua_State; numarg: Integer): lua_Integer; cdecl; + external LUA_LIB name 'luaL_checkinteger'; +function luaL_optinteger(L: Plua_State; narg: Integer; def: lua_Integer): lua_Integer; cdecl; + external LUA_LIB name 'luaL_optinteger'; +procedure luaL_checkstack(L: Plua_State; sz: Integer; const msg: PAnsiChar); cdecl; + external LUA_LIB name 'luaL_checkstack'; +procedure luaL_checktype(L: Plua_State; narg: Integer; t: Integer); cdecl; + external LUA_LIB name 'luaL_checktype'; +procedure luaL_checkany(L: Plua_State; narg: Integer); cdecl; external LUA_LIB name 'luaL_checkany'; +function luaL_newmetatable(L: Plua_State; const tname: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_newmetatable'; +function luaL_checkudata(L: Plua_State; ud: Integer; const tname: PAnsiChar): Pointer; cdecl; + external LUA_LIB name 'luaL_checkudata'; +procedure luaL_where(L: Plua_State; lvl: Integer); cdecl; external LUA_LIB name 'luaL_where'; +function luaL_error(L: Plua_State; const fmt: PAnsiChar): Integer; varargs; cdecl; + external LUA_LIB name 'luaL_error'; +function luaL_checkoption(L: Plua_State; narg: Integer; const def: PAnsiChar; const lst: PPAnsiChar) + : Integer; cdecl; external LUA_LIB name 'luaL_checkoption'; +function luaL_ref(L: Plua_State; t: Integer): Integer; cdecl; external LUA_LIB name 'luaL_ref'; +procedure luaL_unref(L: Plua_State; t: Integer; ref: Integer); cdecl; + external LUA_LIB name 'luaL_unref'; +function luaL_loadfile(L: Plua_State; const filename: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_loadfile'; +function luaL_loadbuffer(L: Plua_State; const buff: PAnsiChar; sz: size_t; const name: PAnsiChar) + : Integer; cdecl; external LUA_LIB name 'luaL_loadbuffer'; +function luaL_loadstring(L: Plua_State; const s: PAnsiChar): Integer; cdecl; + external LUA_LIB name 'luaL_loadstring'; +function luaL_newstate: Plua_State; cdecl; external LUA_LIB name 'luaL_newstate:'; +function luaL_gsub(L: Plua_State; const s: PAnsiChar; const p: PAnsiChar; const r: PAnsiChar) + : PAnsiChar; cdecl; external LUA_LIB name 'luaL_gsub'; +function luaL_findtable(L: Plua_State; idx: Integer; const fname: PAnsiChar; szhint: Integer) + : PAnsiChar; cdecl; external LUA_LIB name 'luaL_findtable'; + +(* + ** =============================================================== + ** some useful macros + ** =============================================================== +*) + +function luaL_argcheck(L: Plua_State; cond: Boolean; numarg: Integer; const extramsg: PAnsiChar) + : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_checkstring(L: Plua_State; n: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_optstring(L: Plua_State; n: Integer; d: PAnsiChar): PAnsiChar; + +{$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_checkint(L: Plua_State; n: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_optint(L: Plua_State; n: Integer; d: lua_Integer): Integer; {$IFDEF HAVEINLINE}inline; + +{$ENDIF} + +function luaL_checklong(L: Plua_State; n: Integer): LongInt; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_optlong(L: Plua_State; n: Integer; d: lua_Integer): LongInt; + +{$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_typename(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_dofile(L: Plua_State; fn: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function luaL_dostring(L: Plua_State; s: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +procedure luaL_getmetatable(L: Plua_State; n: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} +// #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +(* + ** {====================================================== + ** Generic Buffer manipulation + ** ======================================================= +*) + +type + PluaL_Buffer = ^luaL_Buffer; + + luaL_Buffer = record + p: PAnsiChar; (* current position in buffer *) + lvl: Integer; (* number of strings in the stack (level) *) + L: Plua_State; + buffer: array [0 .. LUAL_BUFFERSIZE - 1] of AnsiChar; + end; + + // #define luaL_addchar(B,c) \ + // ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + // (*(B)->p++ = (char)(c))) + // + // (* compatibility only *) + // #define luaL_putchar(B,c) luaL_addchar(B,c) + // + // #define luaL_addsize(B,n) ((B)->p += (n)) + +procedure luaL_buffinit(L: Plua_State; b: PluaL_Buffer); cdecl; + external LUA_LIB name 'luaL_buffinit'; +function luaL_prepbuffer(b: PluaL_Buffer): PAnsiChar; cdecl; + external LUA_LIB name 'luaL_prepbuffer'; +procedure luaL_addlstring(b: PluaL_Buffer; const s: PAnsiChar; L: size_t); cdecl; + external LUA_LIB name 'luaL_addlstring'; +procedure luaL_addstring(b: PluaL_Buffer; const s: PAnsiChar); cdecl; + external LUA_LIB name 'luaL_addstring'; +procedure luaL_addvalue(b: PluaL_Buffer); cdecl; external LUA_LIB name 'luaL_addvalue'; +procedure luaL_pushresult(b: PluaL_Buffer); cdecl; external LUA_LIB name 'luaL_pushresult'; + +(* }====================================================== *) + +(* compatibility with ref system *) + +(* pre-defined references *) +const + LUA_NOREF = - 2; + LUA_REFNIL = - 1; + + // #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + // (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + // + // #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + // + // #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + (* + ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ + ** Lua standard libraries + ** See Copyright Notice in lua.h + *) + + (* Key to file-handle type *) +const + LUA_FILEHANDLE = 'FILE*'; + LUA_COLIBNAME = 'coroutine'; + LUA_TABLIBNAME = 'table'; + LUA_IOLIBNAME = 'io'; + LUA_OSLIBNAME = 'os'; + LUA_STRLIBNAME = 'string'; + LUA_MATHLIBNAME = 'math'; + LUA_DBLIBNAME = 'debug'; + LUA_LOADLIBNAME = 'package'; + +function luaopen_base(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_base'; +function luaopen_table(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_table'; +function luaopen_io(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_io'; +function luaopen_os(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_os'; +function luaopen_string(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_string'; +function luaopen_math(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_math'; +function luaopen_debug(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_debug'; +function luaopen_package(L: Plua_State): Integer; cdecl; external LUA_LIB name 'luaopen_package'; + +(* open all previous libraries *) +procedure luaL_openlibs(L: Plua_State); cdecl; external LUA_LIB name 'luaL_openlibs'; + +// usefull +function lua_app_alloc(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl; +function lua_processsor_loadstream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Integer; +function lua_processsor_loadfile(L: Plua_State; const filename: string; + chunkname: PAnsiChar): Integer; +function lua_processsor_dofile(L: Plua_State; const filename: string; chunkname: PAnsiChar) + : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +function lua_processsor_dostream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Boolean; + +{$IFDEF HAVEINLINE}inline; {$ENDIF} + + +implementation + +uses + sysutils; + +procedure lua_pop(L: Plua_State; n: Integer); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_settop(L, - (n) - 1) +end; + +procedure lua_newtable(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_createtable(L, 0, 0) +end; + +procedure lua_register(L: Plua_State; n: PAnsiChar; f: lua_CFunction); {$IFDEF HAVEINLINE}inline; + +{$ENDIF} + +begin + lua_pushcfunction(L, f); + lua_setglobal(L, n); +end; + +procedure lua_pushcfunction(L: Plua_State; f: lua_CFunction); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_pushcclosure(L, f, 0) +end; + +function lua_isfunction(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) = LUA_TFUNCTION; +end; + +function lua_istable(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) = LUA_TTABLE; +end; + +function lua_islightuserdata(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; + +{$ENDIF} + +begin + Result := lua_type(L, n) = LUA_TLIGHTUSERDATA; +end; + +function lua_isnil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) = LUA_TNIL; +end; + +function lua_isboolean(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) = LUA_TBOOLEAN; +end; + +function lua_isthread(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) = LUA_TTHREAD; +end; + +function lua_isnone(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) = LUA_TNONE; +end; + +function lua_isnoneornil(L: Plua_State; n: Integer): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_type(L, n) <= 0; +end; + +procedure lua_setglobal(L: Plua_State; s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_setfield(L, LUA_GLOBALSINDEX, s) +end; + +procedure lua_getglobal(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_getfield(L, LUA_GLOBALSINDEX, s); +end; + +function lua_tostring(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_tolstring(L, i, nil); +end; + +procedure lua_pushliteral(L: Plua_State; const s: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_pushlstring(L, s, StrLen(s)) +end; + +procedure lua_getregistry(L: Plua_State); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_pushvalue(L, LUA_REGISTRYINDEX); +end; + +function lua_getgccount(L: Plua_State): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_gc(L, LUA_GCCOUNT, 0); +end; + +function luaL_argcheck(L: Plua_State; cond: Boolean; numarg: Integer; const extramsg: PAnsiChar) + : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := cond or (luaL_argerror(L, numarg, extramsg) <> 0) +end; + +function luaL_checkstring(L: Plua_State; n: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := luaL_checklstring(L, n, nil); +end; + +function luaL_optstring(L: Plua_State; n: Integer; d: PAnsiChar): PAnsiChar; + +{$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := luaL_optlstring(L, n, d, nil) +end; + +function luaL_getn(L: Plua_State; idx: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_objlen(L, idx); +end; + +function luaL_checkint(L: Plua_State; n: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := luaL_checkinteger(L, n); +end; + +function luaL_optint(L: Plua_State; n: Integer; d: lua_Integer): Integer; {$IFDEF HAVEINLINE}inline; + +{$ENDIF} + +begin + Result := luaL_optinteger(L, n, d); +end; + +function luaL_checklong(L: Plua_State; n: Integer): LongInt; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := luaL_checkinteger(L, n); +end; + +function luaL_optlong(L: Plua_State; n: Integer; d: lua_Integer): LongInt; + +{$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := luaL_optinteger(L, n, d); +end; + +function luaL_typename(L: Plua_State; i: Integer): PAnsiChar; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := lua_typename(L, lua_type(L, i)); +end; + +function luaL_dofile(L: Plua_State; fn: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := (luaL_loadfile(L, fn) <> 0) or (lua_pcall(L, 0, LUA_MULTRET, 0) <> 0); +end; + +function luaL_dostring(L: Plua_State; s: PAnsiChar): Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + +begin + Result := (luaL_loadstring(L, s) <> 0) or (lua_pcall(L, 0, LUA_MULTRET, 0) <> 0); +end; + +procedure luaL_getmetatable(L: Plua_State; n: PAnsiChar); {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + lua_getfield(L, LUA_REGISTRYINDEX, n); +end; + +function lua_upvalueindex(i: Integer): Integer; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := (LUA_GLOBALSINDEX - (i)); +end; + +function lua_app_alloc(ud, ptr: Pointer; osize, nsize: size_t): Pointer; cdecl; +begin + if (nsize > 0) then + begin + if ptr = nil then + GetMem(Result, nsize) + else + begin + ReallocMem(ptr, nsize); + Result := ptr; + end; + end + else + begin + if ptr <> nil then + FreeMem(ptr); + Result := nil; + end; +end; + +type + TLuaState = ( + lsStart, + lsLessThan, + lsEscape, + lsEscapeClose, + lsLua, + lsLuaBody, + lsLuaBodyEnd, + lsLuaEqual, + lsLuaEqualEnd + ); + PLuaTextProcessor = ^TLuaTextProcessor; + + TLuaTextProcessor = record + stream: TStream; + state: TLuaState; + outbuffer: array [0 .. 1023] of AnsiChar; + end; + +function lua_stream_reader(L: Plua_State; ud: Pointer; sz: Psize_t): PAnsiChar; cdecl; +var + inbuffer : array [0 .. 1023] of AnsiChar; + inlen, outlen: Integer; + pr : PLuaTextProcessor; + pin, pout : PAnsiChar; + c : AnsiChar; + function Append(const str: PAnsiChar; L: Integer): Boolean; + begin + if outlen + L <= sizeof(pr.outbuffer) then + begin + move(str^, pout^, L); + inc(pout, L); + inc(outlen, L); + Result := true; + end + else + Result := false; + end; + +label + redo, + needspace; +begin + pr := PLuaTextProcessor(ud); + inlen := pr.stream.Read(inbuffer, sizeof(inbuffer)); + outlen := 0; + pin := @inbuffer; + pout := @pr.outbuffer; + while (inlen > 0) do + begin + c := pin^; + redo: + case pr.state of + lsStart: + begin + case c of + '<': + pr.state := lsLessThan; + else + if not Append('print("', 7) then + goto needspace; + pr.state := lsEscape; + goto redo; + end; + end; + lsLessThan: + begin + case c of + '%': + pr.state := lsLua; + else + if not Append('print("<', 8) then + goto needspace; + pr.state := lsEscape; + goto redo; + end; + end; + lsEscape: + begin + case c of + '<': + pr.state := lsEscapeClose; + else + case c of + #7: + if not Append('\a', 2) then + goto needspace; + #8: + if not Append('\b', 2) then + goto needspace; + #9: + if not Append('\t', 2) then + goto needspace; + #10: + if not Append('\n")'#10'print("', 12) then + goto needspace; + #11: + if not Append('\v', 2) then + goto needspace; + #13: + if not Append('\r', 2) then + goto needspace; + '\': + if not Append('\\', 2) then + goto needspace; + '"': + if not Append('\"', 2) then + goto needspace; + '''': + if not Append('\''', 2) then + goto needspace; + else + if not Append(pin, 1) then + goto needspace; + end; + end; + end; + lsEscapeClose: + begin + case c of + '%': + begin + if not Append('");', 3) then + goto needspace; + pr.state := lsLua; + end; + else + if not Append('<', 1) then + goto needspace; + pr.state := lsEscape; + goto redo; + end; + end; + lsLua: + begin + case c of + '=': + begin + if not Append('print((', 7) then + goto needspace; + pr.state := lsLuaEqual; + end; + '%': + pr.state := lsLuaBodyEnd; + else + if not Append(pin, 1) then + goto needspace; + pr.state := lsLuaBody; + end; + end; + lsLuaBody: + begin + case c of + '%': + pr.state := lsLuaBodyEnd; + else + if not Append(pin, 1) then + goto needspace; + end; + end; + lsLuaBodyEnd: + begin + case c of + '>': + pr.state := lsStart; + else + if not Append('%', 1) then + goto needspace; + pr.state := lsLuaBody; + goto redo; + end; + end; + lsLuaEqual: + begin + case c of + '%': + pr.state := lsLuaEqualEnd; + else + if not Append(pin, 1) then + goto needspace; + end; + end; + lsLuaEqualEnd: + begin + case c of + '>': + begin + if not Append('));', 3) then + goto needspace; + pr.state := lsStart; + end; + else + if not Append('%', 1) then + goto needspace; + pr.state := lsLuaEqual; + goto redo; + end; + end; + end; + inc(pin); + dec(inlen); + end; + if outlen = 0 then + begin + case pr.state of + lsLessThan: + Append('print("<")', 10); + lsEscape: + Append('")', 2); + lsEscapeClose: + Append('%")', 3); + end; + pr.state := lsStart; + end; + Result := @pr.outbuffer; + sz^ := outlen; + Exit; +needspace: + pr.stream.Seek( - inlen, soFromCurrent); + Result := @pr.outbuffer; + sz^ := outlen; +end; + +function lua_processsor_loadstream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Integer; +var + bom : array [0 .. 2] of Byte; + processor: TLuaTextProcessor; +begin + processor.stream := stream; + processor.state := lsStart; + // skip utf8 bom + stream.Seek(0, soFromBeginning); + if not ((stream.Read(bom, 3) = 3) and (bom[0] = $EF) and (bom[1] = $BB) and (bom[2] = $BF)) then + stream.Seek(0, soFromBeginning); + Result := lua_load(L, @lua_stream_reader, @processor, chunkname); +end; + +function lua_processsor_loadfile(L: Plua_State; const filename: string; + chunkname: PAnsiChar): Integer; +var + stream: TFileStream; +begin + stream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone); + try + Result := lua_processsor_loadstream(L, stream, chunkname); + finally + stream.Free; + end; +end; + +function lua_processsor_dofile(L: Plua_State; const filename: string; chunkname: PAnsiChar) + : Boolean; {$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := (lua_processsor_loadfile(L, filename, chunkname) = 0) and + (lua_pcall(L, 0, LUA_MULTRET, 0) = 0); +end; + +function lua_processsor_dostream(L: Plua_State; stream: TStream; chunkname: PAnsiChar): Boolean; + +{$IFDEF HAVEINLINE}inline; {$ENDIF} + + +begin + Result := (lua_processsor_loadstream(L, stream, chunkname) = 0) and + (lua_pcall(L, 0, LUA_MULTRET, 0) = 0); +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/LuaBind.pas b/samples/serversideviews_lua/lua4delphi/LuaBind.pas new file mode 100644 index 00000000..348b502c --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/LuaBind.pas @@ -0,0 +1,903 @@ +{$WARNINGS OFF} +unit LuaBind; + +interface + +uses LuaBind.Intf, + System.Classes, + System.SysUtils, + System.Rtti, + System.Generics.Collections; + +type + ELuaException = class(Exception) + + end; + + ELuaRuntimeException = class(ELuaException) + + end; + + ELuaConstructorException = class(ELuaException) + + end; + + ELuaSyntaxError = class(ELuaException) + + end; + + ELuaFilterException = class(ELuaSyntaxError) + + end; + + ILuaValue = interface + ['{8621BAD3-B847-4176-937F-2CD016BBE13E}'] + /// /// + function IsNil: boolean; + + function IsNumber: boolean; + function IsInteger: boolean; + function IsString: boolean; + function IsBoolean: boolean; + function IsLightUserData: boolean; + /// /// + function GetAsNumber: Double; + function GetAsInteger: Integer; + function GetAsString: AnsiString; + function GetAsBoolean: boolean; + function GetAsLightUserData: Pointer; + end; + + TLuaValueType = (lvtNil, lvtNumber, lvtInteger, lvtString, lvtBoolean, + lvtLightUserData, lvtTable, lvtFunction, lvtUserData, lvtThread); + + TLuaValue = class(TInterfacedObject, ILuaValue) + strict private + FLuaValueType: TLuaValueType; + + strict private + + protected + /// /// + function IsNil: boolean; + function IsNumber: boolean; + function IsInteger: boolean; + function IsString: boolean; + function IsBoolean: boolean; + function IsLightUserData: boolean; + /// /// + function GetAsNumber: Double; + function GetAsInteger: Integer; + function GetAsString: AnsiString; + function GetAsBoolean: boolean; + function GetAsLightUserData: Pointer; + + private + procedure CheckType(LuaValueType: TLuaValueType); + + protected + FValue: TValue; + constructor Create(LuaState: Plua_State; StackIndex: Integer); + + public + class function GetAsLuaTable(LuaState: Plua_State; + StackIndex: Integer): TValue; + class function GetLuaValueType(LuaState: Plua_State; StackIndex: Integer) + : TLuaValueType; + class function GetTValueFromLuaValueType(LuaValueType: TLuaValueType; + LuaState: Plua_State; StackIndex: Integer): TValue; static; + class function PopTValueFromStack(LuaState: Plua_State): TValue; static; + end; + + ILuaLibraryLoader = interface; + + TLuaEngine = class + strict private + procedure CheckLuaError(const r: Integer); + + private + procedure InternalDeclareTable(AObject: TObject); + + protected + LState: Plua_State; + procedure InitLua; + procedure CloseLua; + + public + constructor Create; overload; virtual; + constructor Create(const AScript: string); overload; virtual; + destructor Destroy; override; + function GetRawLuaState: Plua_State; + + procedure Reset; + procedure LoadScript(const AScript: AnsiString); overload; + procedure LoadScript(const AStream: TStream; + AOwnStream: boolean = true); overload; + procedure LoadFromFile(const AFileName: AnsiString); + procedure Execute; + procedure ExecuteFile(const AFileName: AnsiString); + procedure ExecuteScript(const AScript: AnsiString); + + // PUSH methods for simple types + function DeclareGlobalNil(AName: AnsiString): TLuaEngine; + function DeclareGlobalNumber(AName: AnsiString; AValue: Double): TLuaEngine; + function DeclareGlobalInteger(AName: AnsiString; AValue: Integer) + : TLuaEngine; + function DeclareGlobalString(AName: AnsiString; AValue: AnsiString) + : TLuaEngine; + function DeclareGlobalBoolean(AName: AnsiString; AValue: boolean) + : TLuaEngine; + function DeclareGlobalLightUserData(AName: AnsiString; AValue: Pointer) + : TLuaEngine; + function DeclareGlobalUserData(AName: AnsiString; AValue: Pointer) + : TLuaEngine; + + // PUSH complex types + function DeclareGlobalFunction(AName: AnsiString; AFunction: lua_CFunction) + : TLuaEngine; + + function DeclareGlobalDelphiObjectAsTable(AObject: TObject; + AVariableName: string): TLuaEngine; + + // Helpers to PUSH specific types coping properties or data into Lua tables + function DeclareTable(const ATableName: AnsiString; AKeys: array of string; + AValues: array of string): TLuaEngine; overload; + function DeclareTable(const ATableName: AnsiString; AKeys: array of Integer; + AValues: array of string): TLuaEngine; overload; + function DeclareTable(const ATableName: AnsiString; + ADictionary: TDictionary): TLuaEngine; overload; + function DeclareTable(const ATableName: AnsiString; + ADictionary: TDictionary): TLuaEngine; overload; + function DeclareTable(const ATableName: AnsiString; AObject: TObject) + : TLuaEngine; overload; + + function DeclareTable(const ATableName: AnsiString; __self: Pointer; + AFunctions: TDictionary; + AData: TDictionary + ): TLuaEngine; overload; + + // GET methods for simple types + function GetGlobal(AName: AnsiString): ILuaValue; + + // External load libraries + procedure LoadExternalLibraries(ALuaLibraryLoader: ILuaLibraryLoader); + + // function + function ExecuteFunction(FunctionName: AnsiString; + const Params: array of TValue): TValue; + + // helpers + class function ExecuteWithResult(AScript: AnsiString; + const ParamNames: array of string; + const ParamValues: array of string): string; + end; + + ILuaLibraryLoader = interface + ['{46A7894C-DDA8-4E15-95EB-B52463341FF1}'] + procedure Execute(ALuaEngine: TLuaEngine); + end; + + TLuaUtils = class sealed + public + class procedure PushTValue(L: Plua_State; Value: TValue); static; + end; + +implementation + +uses + typinfo, + LuaBind.DelphiObjects; + +function internal_call_method(LState: Plua_State): Integer; cdecl; +begin + // raise Exception.Create('Error Message'); + lua_pop(LState, 1); + lua_pop(LState, 1); + lua_pushcfunction(LState, @_delphi_call_method); + Result := 1; + // Result := lua_gettop(LState); + // for I := 1 to Result do + // begin + // v := TLuaValue.PopTValueFromStack(LState); + // end + // // Result := _delphi_call_method(LState) +end; + +class procedure TLuaUtils.PushTValue(L: Plua_State; Value: TValue); +var + utf8s: RawByteString; +begin + case Value.Kind of + tkUnknown, tkChar, tkSet, tkMethod, tkVariant, tkArray, tkProcedure, + tkRecord, tkInterface, tkDynArray, tkClassRef: + begin + lua_pushnil(L); + // raise Exception.Create('Unsupported return type: ' + Value.ToString); + end; + tkInteger: + lua_pushinteger(L, Value.AsInteger); + tkEnumeration: + begin + if Value.IsType then + begin + if Value.AsBoolean then + lua_pushboolean(L, 1) + else + lua_pushboolean(L, 0); + end + else + lua_pushinteger(L, Value.AsInteger); + end; + tkFloat: + lua_pushnumber(L, Value.AsExtended); + tkString, tkWChar, tkLString, tkWString, tkUString: + begin + utf8s := UTF8Encode(Value.AsString); + lua_pushstring(L, PAnsiChar(utf8s)); + end; + tkClass: + lua_pushlightuserdata(L, Pointer(Value.AsObject)); + tkInt64: + lua_pushnumber(L, Value.AsInt64); + tkPointer: + lua_pushlightuserdata(L, Pointer(Value.AsObject)); + end; +end; + +{ TLuaEngine } + +constructor TLuaEngine.Create; +begin + inherited Create; + InitLua; +end; + +procedure TLuaEngine.CloseLua; +begin + lua_close(LState); +end; + +constructor TLuaEngine.Create(const AScript: string); +begin + Create; + LoadScript(AScript); +end; + +function TLuaEngine.DeclareGlobalBoolean(AName: AnsiString; AValue: boolean) + : TLuaEngine; +var + b: Integer; +begin + if AValue then + b := 1 + else + b := 0; + lua_pushboolean(LState, b); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalDelphiObjectAsTable(AObject: TObject; + AVariableName: string): TLuaEngine; +begin + // lua_createtable(L, 0, 0); + // lua_createtable(L, 0, 1); + assert(lua_isnil(LState, -1)); + lua_newtable(LState); + assert(lua_istable(LState, -1)); + lua_newtable(LState); + lua_pushcfunction(LState, @internal_call_method); + lua_setfield(LState, -2, '__index'); + lua_setmetatable(LState, -2); + lua_setglobal(LState, PAnsiChar(AnsiString(AVariableName))); + + // http://stackoverflow.com/questions/3449759/lua-c-api-and-metatable-functions + // lua_newtable(LState); + // lua_pushstring(LState, PAnsiChar('__handle__')); + // lua_pushlightuserdata(LState, Pointer(AObject)); + // lua_settable(LState, - 3); + // { + // for prop in ctx.GetType(AObject.ClassInfo).GetProperties do + // begin + // v := prop.GetValue(AObject); + // if v.Kind = tkUnknown then + // continue; + // k := prop.Name; + // TLuaUtils.PushTValue(LState, k); + // TLuaUtils.PushTValue(LState, v); + // lua_settable(LState, - 3); + // end; + // + // for method in ctx.GetType(AObject.ClassInfo).GetMethods + // begin + // if not (method.Visibility in [mvPublic, mvPublished]) then + // continue; + // k := method.Name; + // TLuaUtils.PushTValue(LState, k); + // lua_pushcfunction(LState, @internal_call_method); + // lua_settable(LState, - 3); + // end; + // } + // + // lua_setglobal(LState, PAnsiChar(AnsiString(AVariableName))); + // + // // define metatable + // // lua_createtable(LState, 0, 0); + // lua_createtable(LState, 0, 1); + // lua_pushcfunction(LState, @internal_call_method); + // lua_setfield(LState, - 2, AnsiString('__index')); + // lua_setmetatable(LState, - 2); + // lua_setglobal(LState, PAnsiChar(AnsiString(AVariableName))); +end; + +function TLuaEngine.DeclareGlobalFunction(AName: AnsiString; + AFunction: lua_CFunction): TLuaEngine; +begin + lua_pushcfunction(LState, AFunction); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalInteger(AName: AnsiString; AValue: Integer) + : TLuaEngine; +begin + lua_pushinteger(LState, AValue); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalLightUserData(AName: AnsiString; + AValue: Pointer): TLuaEngine; +begin + lua_pushlightuserdata(LState, AValue); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalNil(AName: AnsiString): TLuaEngine; +begin + lua_pushnil(LState); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalNumber(AName: AnsiString; AValue: Double) + : TLuaEngine; +begin + lua_pushnumber(LState, AValue); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalString(AName: AnsiString; AValue: AnsiString) + : TLuaEngine; +begin + lua_pushstring(LState, PAnsiChar(AValue)); + lua_setglobal(LState, PAnsiChar(AName)); + Result := Self; +end; + +function TLuaEngine.DeclareGlobalUserData(AName: AnsiString; AValue: Pointer) + : TLuaEngine; +begin + raise ELuaException.Create('Not implemented'); + Result := Self; +end; + +function TLuaEngine.DeclareTable(const ATableName: AnsiString; + AKeys: array of Integer; AValues: array of string): TLuaEngine; +var + I: Integer; + k: Integer; + v: string; +begin + lua_newtable(LState); + for I := 0 to high(AKeys) do + begin + k := AKeys[I]; + v := AValues[I]; + TLuaUtils.PushTValue(LState, k); + TLuaUtils.PushTValue(LState, v); + lua_settable(LState, -3); + end; + lua_setglobal(LState, PAnsiChar(ATableName)); + Result := Self; +end; + +function TLuaEngine.DeclareTable(const ATableName: AnsiString; + ADictionary: TDictionary): TLuaEngine; +var + key: TValue; +begin + lua_newtable(LState); + for key in ADictionary.Keys do + begin + TLuaUtils.PushTValue(LState, key); + TLuaUtils.PushTValue(LState, ADictionary.Items[key]); + lua_settable(LState, -3); + end; + lua_setglobal(LState, PAnsiChar(ATableName)); + Result := Self; +end; + +function TLuaEngine.DeclareTable(const ATableName: AnsiString; + ADictionary: TDictionary): TLuaEngine; +var + key: string; +begin + lua_newtable(LState); + for key in ADictionary.Keys do + begin + TLuaUtils.PushTValue(LState, key); + TLuaUtils.PushTValue(LState, ADictionary.Items[key]); + lua_settable(LState, -3); + end; + lua_setglobal(LState, PAnsiChar(ATableName)); +end; + +function TLuaEngine.DeclareTable(const ATableName: AnsiString; + AKeys: array of string; AValues: array of string): TLuaEngine; +var + I: Integer; + k: string; + v: string; +begin + lua_newtable(LState); + for I := 0 to high(AKeys) do + begin + k := AKeys[I]; + v := AValues[I]; + TLuaUtils.PushTValue(LState, k); + TLuaUtils.PushTValue(LState, v); + lua_settable(LState, -3); + end; + lua_setglobal(LState, PAnsiChar(ATableName)); +end; + +destructor TLuaEngine.Destroy; +begin + CloseLua; + inherited; +end; + +procedure TLuaEngine.Execute; +var + r: Integer; +begin + r := lua_pcall(LState, 0, 0, 0); + CheckLuaError(r); +end; + +procedure TLuaEngine.CheckLuaError(const r: Integer); +var + err: PAnsiChar; +begin + case r of + // success + 0: + begin + + end; + // a runtime error. + LUA_ERRRUN: + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaRuntimeException.CreateFmt('Runtime error [%s]', [err]); + end; + // memory allocation error. For such errors, Lua does not call the error handler function. + LUA_ERRMEM: + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.CreateFmt('Memory allocation error [%s]', [err]); + end; + // error while running the error handler function. + LUA_ERRERR: + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.CreateFmt + ('Error while running the error handler function [%s]', [err]); + end; + LUA_ERRSYNTAX: + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaSyntaxError.CreateFmt('Syntax Error [%s]', [err]); + end + else + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.CreateFmt('Unknown Error [%s]', [err]); + end; + end; +end; + +procedure TLuaEngine.ExecuteFile(const AFileName: AnsiString); +begin + LoadFromFile(AFileName); + Execute; +end; + +function TLuaEngine.ExecuteFunction(FunctionName: AnsiString; + const Params: array of TValue): TValue; +var + p: TValue; + r: Integer; +begin + lua_getglobal(LState, PAnsiChar(FunctionName)); + for p in Params do + TLuaUtils.PushTValue(LState, p); + r := lua_pcall(LState, Length(Params), 1, 0); + CheckLuaError(r); + Result := TLuaValue.PopTValueFromStack(LState); +end; + +function TLuaEngine.GetGlobal(AName: AnsiString): ILuaValue; +begin + lua_getglobal(LState, PAnsiChar(AName)); + Result := TLuaValue.Create(LState, -1); +end; + +function TLuaEngine.GetRawLuaState: Plua_State; +begin + Result := LState; +end; + +procedure TLuaEngine.InitLua; +begin + LState := lua_open; + if not assigned(LState) then + raise ELuaException.Create('Cannot initialize Lua'); + luaL_openlibs(LState); +end; + +procedure TLuaEngine.LoadExternalLibraries(ALuaLibraryLoader + : ILuaLibraryLoader); +begin + ALuaLibraryLoader.Execute(Self); +end; + +procedure TLuaEngine.LoadFromFile(const AFileName: AnsiString); +var + err: PAnsiChar; +begin + if luaL_loadfile(LState, PAnsiChar(AFileName)) <> 0 then + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.Create(err); + end; +end; + +procedure TLuaEngine.LoadScript(const AStream: TStream; AOwnStream: boolean); +var + sr: TStreamReader; + s: string; +begin + sr := TStreamReader.Create(AStream); + try + if AOwnStream then + sr.OwnStream; + s := sr.ReadToEnd; + LoadScript(s); + finally + sr.Free; + end; +end; + +procedure TLuaEngine.Reset; +begin + CloseLua; + InitLua; +end; + +procedure TLuaEngine.ExecuteScript(const AScript: AnsiString); +var + err: PAnsiChar; +begin + if luaL_dostring(LState, PAnsiChar(AScript)) then + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.Create(err); + end; +end; + +class function TLuaEngine.ExecuteWithResult(AScript: AnsiString; + const ParamNames, ParamValues: array of string): string; +var + L: TLuaEngine; + I: Integer; +begin + L := TLuaEngine.Create; + try + L.LoadScript(AScript); + if Length(ParamNames) <> Length(ParamValues) then + raise ELuaRuntimeException.Create + ('Number of params names and param values is not equals'); + for I := 0 to Length(ParamNames) - 1 do + L.DeclareGlobalString(ParamNames[I], ParamValues[I]); + L.Execute; + finally + L.Free; + end; +end; + +procedure TLuaEngine.LoadScript(const AScript: AnsiString); +var + err: PAnsiChar; +begin + if luaL_loadstring(LState, PAnsiChar(AScript)) <> 0 then + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.Create(err); + end; +end; + +procedure TLuaEngine.InternalDeclareTable(AObject: TObject); +var + prop: TRTTIProperty; + ctx: TRTTIContext; + properties: TArray; + k: AnsiString; + Value: TValue; + o: TObject; +begin + ctx := TRTTIContext.Create; + try + lua_newtable(LState); + properties := ctx.GetType(AObject.ClassType).GetProperties; + for prop in properties do + begin + if not(prop.Visibility in [mvPublic, mvPublished]) then + continue; + k := prop.Name; + TLuaUtils.PushTValue(LState, k); + Value := prop.GetValue(AObject); + if Value.TypeInfo^.Kind = tkClass then + begin + o := Value.AsObject; + if not assigned(o) then + lua_pushnil(LState) + else + InternalDeclareTable(Value.AsObject); + end + else + begin + if Value.Kind = tkEnumeration then + begin + Value := prop.GetValue(AObject).AsOrdinal; + end; + TLuaUtils.PushTValue(LState, Value) + end; + lua_settable(LState, -3); + end; + finally + ctx.Free; + end; +end; + +function TLuaEngine.DeclareTable(const ATableName: AnsiString; AObject: TObject) + : TLuaEngine; +begin + InternalDeclareTable(AObject); + lua_setglobal(LState, PAnsiChar(ATableName)); +end; + +function TLuaEngine.DeclareTable(const ATableName: AnsiString; __self: Pointer; + AFunctions: TDictionary; + AData: TDictionary): TLuaEngine; +var + key: string; +begin + lua_newtable(LState); + TLuaUtils.PushTValue(LState, '__self'); + lua_pushlightuserdata(LState, __self); + lua_settable(LState, -3); + for key in AFunctions.Keys do + begin + TLuaUtils.PushTValue(LState, key); + lua_pushcfunction(LState, AFunctions[key]); + lua_settable(LState, -3); + end; + + if Assigned(AData) then + begin + for key in AData.Keys do + begin + TLuaUtils.PushTValue(LState, key); + TLuaUtils.PushTValue(LState, AData[key]); + lua_settable(LState, -3); + end; + end; + + lua_setglobal(LState, PAnsiChar(ATableName)); +end; + +{ TLuaValue } + +class function TLuaValue.GetTValueFromLuaValueType(LuaValueType: TLuaValueType; + LuaState: Plua_State; StackIndex: Integer): TValue; +var + a: AnsiString; +begin + case LuaValueType of + lvtNil: + Result := nil; + + lvtNumber: + Result := lua_tonumber(LuaState, StackIndex); + + lvtInteger: + Result := lua_tointeger(LuaState, StackIndex); + + lvtString: + begin + a := lua_tostring(LuaState, StackIndex); + Result := a; + end; + + lvtBoolean: + Result := lua_toboolean(LuaState, StackIndex) = 1; + + lvtLightUserData: + Result := TObject(lua_topointer(LuaState, StackIndex)); + + lvtTable: + begin + Result := GetAsLuaTable(LuaState, StackIndex); + end; + + lvtFunction: + begin + raise ELuaException.Create('Not implemented'); + // _lua_CFunction := lua_tocfunction(LuaState, StackIndex); + Result := nil; { todo } + end; + + lvtUserData: + raise ELuaException.Create('UserData not allowed here'); + + lvtThread: + begin + raise ELuaException.Create('Not implemented'); + // _pluastate := lua_tothread(LuaState, StackIndex); + Result := nil; { todo } + end; + end; +end; + +constructor TLuaValue.Create(LuaState: Plua_State; StackIndex: Integer); +begin + inherited Create; + FLuaValueType := GetLuaValueType(LuaState, StackIndex); + FValue := GetTValueFromLuaValueType(FLuaValueType, LuaState, StackIndex); +end; + +class function TLuaValue.GetLuaValueType(LuaState: Plua_State; + StackIndex: Integer): TLuaValueType; +begin + Result := lvtNil; + case lua_type(LuaState, StackIndex) of + lua_tnil: + Result := lvtNil; + LUA_TNUMBER: + Result := lvtNumber; + LUA_TBOOLEAN: + Result := lvtBoolean; + LUA_TSTRING: + Result := lvtString; + LUA_TTABLE: + Result := lvtTable; + LUA_TFUNCTION: + Result := lvtFunction; + LUA_TUSERDATA: + Result := lvtUserData; + LUA_TTHREAD: + Result := lvtThread; + LUA_TLIGHTUSERDATA: + Result := lvtLightUserData; + LUA_TNONE: + raise ELuaException.Create('Invalid stack index location'); + end; +end; + +procedure TLuaValue.CheckType(LuaValueType: TLuaValueType); +begin + if FLuaValueType <> LuaValueType then + raise ELuaException.Create('Cannot access value as ' + + GetEnumName(TypeInfo(TLuaValueType), Ord(LuaValueType)) + ' while it is ' + + GetEnumName(TypeInfo(TLuaValueType), Ord(FLuaValueType))); +end; + +function TLuaValue.GetAsBoolean: boolean; +begin + CheckType(lvtBoolean); + Result := FValue.AsBoolean; +end; + +function TLuaValue.GetAsInteger: Integer; +begin + Result := 0; + if Self.FLuaValueType = lvtNumber then + begin + if GetAsNumber = Trunc(GetAsNumber) then + Result := Trunc(GetAsNumber) + else + CheckType(lvtInteger); + end + else + begin + CheckType(lvtInteger); + Result := FValue.AsInteger; + end; +end; + +function TLuaValue.GetAsLightUserData: Pointer; +begin + CheckType(lvtLightUserData); + Result := Pointer(FValue.AsObject); +end; + +class function TLuaValue.GetAsLuaTable(LuaState: Plua_State; + StackIndex: Integer): TValue; +begin + raise ELuaException.Create('Not implemented'); +end; + +function TLuaValue.GetAsNumber: Double; +begin + CheckType(lvtNumber); + Result := FValue.AsExtended; +end; + +function TLuaValue.GetAsString: AnsiString; +begin + CheckType(lvtString); + Result := FValue.AsString; +end; + +function TLuaValue.IsBoolean: boolean; +begin + Result := FLuaValueType = lvtBoolean; +end; + +function TLuaValue.IsInteger: boolean; +begin + Result := FLuaValueType = lvtInteger; +end; + +function TLuaValue.IsLightUserData: boolean; +begin + Result := FLuaValueType = lvtLightUserData; +end; + +function TLuaValue.IsNil: boolean; +begin + Result := FLuaValueType = lvtNil; +end; + +function TLuaValue.IsNumber: boolean; +begin + Result := FLuaValueType = lvtNumber; +end; + +function TLuaValue.IsString: boolean; +begin + Result := FLuaValueType = lvtString; +end; + +class function TLuaValue.PopTValueFromStack(LuaState: Plua_State): TValue; +var + lvt: TLuaValueType; +begin + lvt := TLuaValue.GetLuaValueType(LuaState, -1); + Result := TLuaValue.GetTValueFromLuaValueType(lvt, LuaState, -1); + lua_pop(LuaState, 1); +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/README.md b/samples/serversideviews_lua/lua4delphi/README.md new file mode 100644 index 00000000..fa0a1c27 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/README.md @@ -0,0 +1,4 @@ +# lua4delphi +Delphi binding for Lua 5.1 language + +This project was initially part of [DelphiMVCFramework](https://github.com/danieleteti/delphimvcframework) but now it is an indipendent project. diff --git a/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dpr b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dpr new file mode 100644 index 00000000..2ceabe90 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dpr @@ -0,0 +1,27 @@ +program LuaEmbedded; + +{$APPTYPE CONSOLE} + +{$R *.res} + + +uses + LuaBind.Filters.Text, + System.IOUtils; + +var + eLuaFilter: TLuaEmbeddedTextFilter; + +begin + eLuaFilter := TLuaEmbeddedTextFilter.Create; + try + eLuaFilter.OutputFunction := 'io.write'; + eLuaFilter.TemplateCode := TFile.ReadAllText(ParamStr(1)); + eLuaFilter.Execute; + + TFile.WriteAllText(TPath.ChangeExtension(ParamStr(1), '.lua'), eLuaFilter.LuaCode); + finally + eLuaFilter.Free; + end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dproj b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dproj new file mode 100644 index 00000000..deb7d810 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/01/LuaEmbedded.dproj @@ -0,0 +1,954 @@ + + + {D2CDB6BD-1AC1-49D5-87D9-23DAE45069D0} + 19.3 + None + LuaEmbedded.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + LuaEmbedded + $(BDS)\bin\delphi_PROJECTICNS.icns + $(BDS)\bin\delphi_PROJECTICON.ico + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + fmx;IndySystem;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;DBXOracleDriver;CustomIPTransport;AureliusXE2;dsnap;IndyCore;fmxase;inetdbxpress;IPIndyImpl;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;bindengine;soaprtl;DBXInformixDriver;DBXFirebirdDriver;inet;fmxobj;LKSL;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;$(DCC_UsePackage) + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + + + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + Debug + true + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + true + true + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + true + Base + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + true + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + JvGlobus;JvMM;JvDlgs;JvCrypt;TeeDB;Rave100VCL;vclib;inetdbbde;DBXSybaseASEDriver;vclimg;DataBindingsVCL160;fmi;vcldb;vcldsnap;dac160;unidacvcl160;DBXDb2Driver;Intraweb_120_160;dwsLibRuntime;JvCore;vclribbon;frxe16;vcl;CloudService;DBXMSSQLDriver;CodeSiteExpressPkg;unidac160;FmxTeeUI;JvAppFrm;JvRuntimeDesign;webdsnap;JclDeveloperTools;adortl;JvWizards;SimpleGraphPackage;NewAC;OpenWirePkgD16;vcldbx;frx16;DotNet4Delphi_XE2;crcontrols160;JclContainers;Tee;DataBindings;DBXOdbcDriver;JvCmp;JvSystem;svnui;adgrmxe2;JvControls;frxDB16;intrawebdb_120_160;fs16;vclactnband;FMXTee;TeeUI;bindcompvcl;JvStdCtrls;JvCustom;Jcl;vclie;vcltouch;dacvcl160;websnap;VclSmp;fsDB16;DataSnapConnectors;RlxPackage;dsnapcon;JclVcl;JvPascalInterpreter;vclx;Lua4Delphi;svn;bdertl;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + + + TeeDB;vclib;DBXSybaseASEDriver;vclimg;vcldb;vcldsnap;DBXDb2Driver;vcl;DBXMSSQLDriver;webdsnap;adortl;Tee;DBXOdbcDriver;adgrmxe2;vclactnband;TeeUI;bindcompvcl;vclie;vcltouch;websnap;VclSmp;DataSnapConnectors;dsnapcon;vclx;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + false + true + true + true + + + test01.elua + ..\..\;$(DCC_UnitSearchPath) + None + 1033 + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + (untitled) + (untitled) + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + LuaEmbedded.dpr + + + + + + + true + + + + + true + + + + + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + False + False + False + True + False + + + 12 + + + + + diff --git a/samples/serversideviews_lua/lua4delphi/samples/01/Win32/Debug/test01.elua b/samples/serversideviews_lua/lua4delphi/samples/01/Win32/Debug/test01.elua new file mode 100644 index 00000000..2f96a931 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/01/Win32/Debug/test01.elua @@ -0,0 +1,13 @@ +This is a normal text file +but now I'm start a Lua tag + +And now back to the simple text mode +Expressions are supported too. +Do you know what is the result of 5*5? +5*5 = +bye bye \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dpr b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dpr new file mode 100644 index 00000000..365a57e3 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dpr @@ -0,0 +1,39 @@ +program LuaConsole; + +{$APPTYPE CONSOLE} +{$R *.res} + +uses + LuaBind, + System.SysUtils, + LuaBind.Intf in '..\..\LuaBind.Intf.pas'; + +var + LuaEngine: TLuaEngine; + ScriptDir, PackagePathToAppend: string; + +begin + try + LuaEngine := TLuaEngine.Create; + try + ScriptDir := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(1))); + PackagePathToAppend := ScriptDir + '?.lua'; + LuaEngine.ExecuteScript('package.path = package.path .. ";' + + PackagePathToAppend.Replace('\', '\\') + '"' + sLineBreak + + '__SCRIPTFILE__ = "' + ParamStr(1).Replace('\', '\\') + '"' + + sLineBreak + + '__SCRIPTDIR__ = "' + ScriptDir.Replace('\', '\\') + '"' + + sLineBreak); + LuaEngine.LoadFromFile(ParamStr(1)); + LuaEngine.Execute; + finally + LuaEngine.Free; + end; + except + on E: Exception do + Writeln(E.ClassName, ': ', E.Message); + end; + if DebugHook <> 0 then + readln; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dproj b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dproj new file mode 100644 index 00000000..ded31c90 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/02/LuaConsole.dproj @@ -0,0 +1,994 @@ + + + {F33CC2C0-360B-4A50-8D01-0DFBCF12DFD3} + 19.3 + None + LuaConsole.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + LuaConsole + $(BDS)\bin\delphi_PROJECTICNS.icns + $(BDS)\bin\delphi_PROJECTICON.ico + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + + + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + Debug + true + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + true + true + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + true + Base + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + true + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + true + Base + true + true + IndyIPClient;AnyDAC_PhysADS_D18;AnyDAC_PhysODBC_D18;AnyDAC_GUIxForms_D18;DBXSqliteDriver;AnyDAC_ComI_D18;AnyDAC_PhysTDBX_D18;fmx;IndySystem;AnyDAC_PhysIB_D18;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;AnyDAC_PhysMSAcc_D18;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;AnyDAC_PhysPg_D18;fmxase;IndyCore;IndyIPCommon;CloudService;FmxTeeUI;AnyDAC_PhysMSSQL_D18;AnyDAC_PhysOracle_D18;inetdbxpress;AnyDAC_PhysMySQL_D18;AnyDAC_Phys_D18;AnyDAC_Comp_D18;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;bindengine;soaprtl;bindcompdbx;FMXTee;AnyDAC_PhysASA_D18;DBXInformixDriver;DBXFirebirdDriver;AnyDAC_PhysSQLITE_D18;inet;fmxobj;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;AnyDAC_PhysDb2_D18;$(DCC_UsePackage);$(DCC_UsePackage) + + + None + true + ..\..\;$(DCC_UnitSearchPath) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + D:\DEV\bitPresenze30\servers\bpserver\data\e.lua + IndyIPClient;AnyDAC_PhysADS_D18;AnyDAC_PhysODBC_D18;AnyDAC_GUIxForms_D18;NxGridDsgn_dxe3;DBXSqliteDriver;frxDB18;AnyDAC_ComI_D18;AnyDAC_PhysTDBX_D18;tmswizdXE4;fmx;IndySystem;TeeDB;frx18;AnyDAC_PhysIB_D18;inetdbbde;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;sample01adapters;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;NxDBGridDsgn_dxe3;vcldb;vcldsnap;AnyDAC_PhysMSAcc_D18;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;NxDBGridRun_dxe3;vclribbon;dsnap;IndyIPServer;AnyDAC_PhysPg_D18;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;CodeSiteExpressPkg;AnyDAC_PhysMSSQL_D18;AnyDAC_PhysOracle_D18;inetdbxpress;webdsnap;AnyDAC_PhysMySQL_D18;NxCollectionRun_dxe3;adortl;CustomAdaptersMDPackage;AnyDAC_Phys_D18;NxCollectionDsgn_dxe3;NxGridRun_dxe3;NxCommonDsgn_dxe3;AnyDAC_Comp_D18;NxCommonRun_dxe3;bindcompfmx;tmsdXE4;BPAdapters;vcldbx;TextPkg;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;Tee;DBXOdbcDriver;NxAddonsRun_dxe3;dorm_runtime_xe4;xmlrtl;svnui;ibxpress;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;frxe18;vclactnband;bindengine;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;vcltouch;AnyDAC_PhysASA_D18;tmsexdXE4;VclSmp;DBXInformixDriver;Intraweb;DataSnapConnectors;NxInspectorRun_dxe3;dsnapcon;DBXFirebirdDriver;AnyDAC_PhysSQLITE_D18;inet;tmsxlsdXE4;fmxobj;vclx;svn;DBXSybaseASADriver;fmxdae;NxInspectorDsgn_dxe3;bdertl;VirtualTreesR;dbexpress;DataSnapIndy10ServerTransport;AnyDAC_PhysDb2_D18;$(DCC_UsePackage) + 1033 + + + true + IndyIPClient;AnyDAC_PhysADS_D18;AnyDAC_PhysODBC_D18;AnyDAC_GUIxForms_D18;NxGridDsgn_dxe3;DBXSqliteDriver;AnyDAC_ComI_D18;AnyDAC_PhysTDBX_D18;fmx;IndySystem;TeeDB;AnyDAC_PhysIB_D18;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;MetropolisUILiveTile;NxDBGridDsgn_dxe3;vcldb;vcldsnap;AnyDAC_PhysMSAcc_D18;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;NxDBGridRun_dxe3;vclribbon;dsnap;IndyIPServer;AnyDAC_PhysPg_D18;fmxase;vcl;IndyCore;IndyIPCommon;CloudService;DBXMSSQLDriver;FmxTeeUI;AnyDAC_PhysMSSQL_D18;AnyDAC_PhysOracle_D18;inetdbxpress;webdsnap;AnyDAC_PhysMySQL_D18;NxCollectionRun_dxe3;adortl;AnyDAC_Phys_D18;NxCollectionDsgn_dxe3;NxGridRun_dxe3;NxCommonDsgn_dxe3;AnyDAC_Comp_D18;NxCommonRun_dxe3;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;Tee;DBXOdbcDriver;NxAddonsRun_dxe3;xmlrtl;ibxpress;NxSheetRun_dxe3;IndyProtocols;DBXMySQLDriver;vclactnband;bindengine;soaprtl;bindcompdbx;FMXTee;TeeUI;bindcompvcl;vclie;vcltouch;AnyDAC_PhysASA_D18;VclSmp;DBXInformixDriver;Intraweb;DataSnapConnectors;NxInspectorRun_dxe3;dsnapcon;DBXFirebirdDriver;AnyDAC_PhysSQLITE_D18;inet;fmxobj;vclx;DBXSybaseASADriver;fmxdae;NxInspectorDsgn_dxe3;VirtualTreesR;dbexpress;DataSnapIndy10ServerTransport;AnyDAC_PhysDb2_D18;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + None + 1033 + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + LuaConsole.dpr + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + + + + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + LuaConsole.exe + true + + + + + + true + + + + + true + + + + + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + False + False + False + False + True + False + + + 12 + + + + + diff --git a/samples/serversideviews_lua/lua4delphi/samples/02/Win32/Debug/e.lua b/samples/serversideviews_lua/lua4delphi/samples/02/Win32/Debug/e.lua new file mode 100644 index 00000000..df0587bc --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/02/Win32/Debug/e.lua @@ -0,0 +1,13 @@ +--print(package.path) + +--[[ +require'lfs' + +print(lfs.currentdir ()) + +--table.foreach(_G, print) +]] + +for i= 0,9 do + print(i) +end \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/config.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/config.lua new file mode 100644 index 00000000..f504b5a9 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/config.lua @@ -0,0 +1,20 @@ +-- configuration file for program `pp' +-- define window size + +theform = { + f = form, + setcaption = function (value) + _setcaption(theform.f, value) + end +} + +width = 200 +height = x1+x2+x3; +stringa = 'UPPERCASE='..delphiuppercase('daniele teti').. + 'Nome: '..daniele.nome.. + 'Cognome: '..daniele.cognome.. + 'Età: '..daniele.eta.. + 'Il nome completo è: '..daniele:fullname() + +--theform:setcaption("Hello World") +_setcaption( form, "ciao mondo" ) \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/dumper.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/dumper.lua new file mode 100644 index 00000000..e60cdc90 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/dumper.lua @@ -0,0 +1,229 @@ +--[[ DataDumper.lua +Copyright (c) 2007 Olivetti-Engineering SA + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +]] + +local dumplua_closure = [[ +local closures = {} +local function closure(t) + closures[#closures+1] = t + t[1] = assert(loadstring(t[1])) + return t[1] +end + +for _,t in pairs(closures) do + for i = 2,#t do + debug.setupvalue(t[1], i-1, t[i]) + end +end +]] + +local lua_reserved_keywords = { + 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', + 'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', + 'return', 'then', 'true', 'until', 'while' } + +local function keys(t) + local res = {} + local oktypes = { stringstring = true, numbernumber = true } + local function cmpfct(a,b) + if oktypes[type(a)..type(b)] then + return a < b + else + return type(a) < type(b) + end + end + for k in pairs(t) do + res[#res+1] = k + end + table.sort(res, cmpfct) + return res +end + +local c_functions = {} +for _,lib in pairs{'_G', 'string', 'table', 'math', + 'io', 'os', 'coroutine', 'package', 'debug'} do + local t = _G[lib] or {} + lib = lib .. "." + if lib == "_G." then lib = "" end + for k,v in pairs(t) do + if type(v) == 'function' and not pcall(string.dump, v) then + c_functions[v] = lib..k + end + end +end + +function DataDumper(value, varname, fastmode, ident) + local defined, dumplua = {} + -- Local variables for speed optimization + local string_format, type, string_dump, string_rep = + string.format, type, string.dump, string.rep + local tostring, pairs, table_concat = + tostring, pairs, table.concat + local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0 + setmetatable(strvalcache, {__index = function(t,value) + local res = string_format('%q', value) + t[value] = res + return res + end}) + local fcts = { + string = function(value) return strvalcache[value] end, + number = function(value) return value end, + boolean = function(value) return tostring(value) end, + ['nil'] = function(value) return 'nil' end, + ['function'] = function(value) + return string_format("loadstring(%q)", string_dump(value)) + end, + userdata = function() error("Cannot dump userdata") end, + thread = function() error("Cannot dump threads") end, + } + local function test_defined(value, path) + if defined[value] then + if path:match("^getmetatable.*%)$") then + out[#out+1] = string_format("s%s, %s)\n", path:sub(2,-2), defined[value]) + else + out[#out+1] = path .. " = " .. defined[value] .. "\n" + end + return true + end + defined[value] = path + end + local function make_key(t, key) + local s + if type(key) == 'string' and key:match('^[_%a][_%w]*$') then + s = key .. "=" + else + s = "[" .. dumplua(key, 0) .. "]=" + end + t[key] = s + return s + end + for _,k in ipairs(lua_reserved_keywords) do + keycache[k] = '["'..k..'"] = ' + end + if fastmode then + fcts.table = function (value) + -- Table value + local numidx = 1 + out[#out+1] = "{" + for key,val in pairs(value) do + if key == numidx then + numidx = numidx + 1 + else + out[#out+1] = keycache[key] + end + local str = dumplua(val) + out[#out+1] = str.."," + end + if string.sub(out[#out], -1) == "," then + out[#out] = string.sub(out[#out], 1, -2); + end + out[#out+1] = "}" + return "" + end + else + fcts.table = function (value, ident, path) + if test_defined(value, path) then return "nil" end + -- Table value + local sep, str, numidx, totallen = " ", {}, 1, 0 + local meta, metastr = (debug or getfenv()).getmetatable(value) + if meta then + ident = ident + 1 + metastr = dumplua(meta, ident, "getmetatable("..path..")") + totallen = totallen + #metastr + 16 + end + for _,key in pairs(keys(value)) do + local val = value[key] + local s = "" + local subpath = path + if key == numidx then + subpath = subpath .. "[" .. numidx .. "]" + numidx = numidx + 1 + else + s = keycache[key] + if not s:match "^%[" then subpath = subpath .. "." end + subpath = subpath .. s:gsub("%s*=%s*$","") + end + s = s .. dumplua(val, ident+1, subpath) + str[#str+1] = s + totallen = totallen + #s + 2 + end + if totallen > 80 then + sep = "\n" .. string_rep(" ", ident+1) + end + str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-3).."}" + if meta then + sep = sep:sub(1,-3) + return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")" + end + return str + end + fcts['function'] = function (value, ident, path) + if test_defined(value, path) then return "nil" end + if c_functions[value] then + return c_functions[value] + elseif debug == nil or debug.getupvalue(value, 1) == nil then + return string_format("loadstring(%q)", string_dump(value)) + end + closure_cnt = closure_cnt + 1 + local res = {string.dump(value)} + for i = 1,math.huge do + local name, v = debug.getupvalue(value,i) + if name == nil then break end + res[i+1] = v + end + return "closure " .. dumplua(res, ident, "closures["..closure_cnt.."]") + end + end + function dumplua(value, ident, path) + return fcts[type(value)](value, ident, path) + end + if varname == nil then + varname = "return " + elseif varname:match("^[%a_][%w_]*$") then + varname = varname .. " = " + end + if fastmode then + setmetatable(keycache, {__index = make_key }) + out[1] = varname + table.insert(out,dumplua(value, 0)) + return table.concat(out) + else + setmetatable(keycache, {__index = make_key }) + local items = {} + for i=1,10 do items[i] = '' end + items[3] = dumplua(value, ident or 0, "t") + if closure_cnt > 0 then + items[1], items[6] = dumplua_closure:match("(.*\n)\n(.*)") + out[#out+1] = "" + end + if #out > 0 then + items[2], items[4] = "local t = ", "\n" + items[5] = table.concat(out) + items[7] = varname .. "t" + else + items[2] = varname + end + return table.concat(items) + end +end diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.elua new file mode 100644 index 00000000..f8871933 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.elua @@ -0,0 +1,5 @@ +Ciao + +mondo + +close \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.lua new file mode 100644 index 00000000..1bf01ea4 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/001_very_simple.lua @@ -0,0 +1,10 @@ +io.write [[ +Ciao +]] io.write("hello") +io.write [[ + +mondo +]] io.write("world") +io.write [[ + +close]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.elua new file mode 100644 index 00000000..51044dd1 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.elua @@ -0,0 +1,6 @@ +Ciao + +mondo + +Hi, my name is . What's your name? +close \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.lua new file mode 100644 index 00000000..a49379a9 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/002_very_simple_expressions.lua @@ -0,0 +1,13 @@ +io.write [[ +Ciao +]] io.write("hello") +io.write [[ + +mondo +]] io.write("world") +io.write [[ + +Hi, my name is ]]io.write( "Daniele Teti" ) +io.write [[ +. What's your name? +close]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.elua new file mode 100644 index 00000000..2fe3f521 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.elua @@ -0,0 +1,26 @@ + + +Hello DWS + + +

Hello DWS

+

This page was generated at .

+

Some test links

+

Some facts:

    '); + print_facts(i); + print(''); +end +?> +

+ + \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.lua new file mode 100644 index 00000000..4e279a3a --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/003_index.lua @@ -0,0 +1,29 @@ +io.write [[ + + +Hello DWS + + +

Hello DWS

+

This page was generated at .

+

Some test links

+

Some facts:

    ]] + +function print_facts(i) + print(tostring(i) .. ' + ' .. tostring(i) .. ' = ' .. tostring(i+i)) +end + +for i = 1,5 do + print('
  • '); + print_facts(i); + print('
  • '); +end + +io.write [[ + +

+ +]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.elua new file mode 100644 index 00000000..e69de29b diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/004_empty.lua new file mode 100644 index 00000000..e69de29b diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.elua new file mode 100644 index 00000000..9e21ae5a --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.elua @@ -0,0 +1,2 @@ + +Hello World \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.lua new file mode 100644 index 00000000..2cd0861f --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/005_start_with_lua.lua @@ -0,0 +1,6 @@ + local x = 1 +io.write [[ + +Hello World ]]io.write( x) +io.write [[ +]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.elua new file mode 100644 index 00000000..0cae4c2a --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.elua @@ -0,0 +1,9 @@ +Hello There + + +" +?> + \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.lua new file mode 100644 index 00000000..4018596e --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/006_tag_into_literal_string.lua @@ -0,0 +1,18 @@ +io.write [[ +Hello There +]] +local x = "This is an open tag " + +io.write [[ + +]]io.write(y) +io.write [[ +]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.elua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.elua new file mode 100644 index 00000000..28da7872 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.elua @@ -0,0 +1,9 @@ +Hello There + + + + \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.lua new file mode 100644 index 00000000..07c8a56e --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/007_escaped_quote_into_literal_string.lua @@ -0,0 +1,18 @@ +io.write [[ +Hello There +]] +local x = "Here there is an \" escaped double quote\"" + +io.write [[ + +]]io.write(x) +io.write [[ + +]] +local y = "Here there is only one \" escaped double quote" + +io.write [[ + +]]io.write(y) +io.write [[ +]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/luaexec.bat b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/luaexec.bat new file mode 100644 index 00000000..531fed66 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/embeddedtextfiltertests/luaexec.bat @@ -0,0 +1 @@ +lua %1 > "%1.txt" \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/logging.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/logging.lua new file mode 100644 index 00000000..04a86cb6 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/logging.lua @@ -0,0 +1,189 @@ +------------------------------------------------------------------------------- +-- includes a new tostring function that handles tables recursively +-- +-- @author Danilo Tuler (tuler@ideais.com.br) +-- @author Andre Carregal (info@keplerproject.org) +-- @author Thiago Costa Ponte (thiago@ideais.com.br) +-- +-- @copyright 2004-2011 Kepler Project +------------------------------------------------------------------------------- + +local type, table, string, _tostring, tonumber = type, table, string, tostring, tonumber +local select = select +local error = error +local format = string.format + +module("logging") + +-- Meta information +_COPYRIGHT = "Copyright (C) 2004-2011 Kepler Project" +_DESCRIPTION = "A simple API to use logging features in Lua" +_VERSION = "LuaLogging 1.1.4" + +-- The DEBUG Level designates fine-grained instring.formational events that are most +-- useful to debug an application +DEBUG = "DEBUG" + +-- The INFO level designates instring.formational messages that highlight the +-- progress of the application at coarse-grained level +INFO = "INFO" + +-- The WARN level designates potentially harmful situations +WARN = "WARN" + +-- The ERROR level designates error events that might still allow the +-- application to continue running +ERROR = "ERROR" + +-- The FATAL level designates very severe error events that will presumably +-- lead the application to abort +FATAL = "FATAL" + +local LEVEL = {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"} +local MAX_LEVELS = #LEVEL +-- make level names to order +for i=1,MAX_LEVELS do + LEVEL[LEVEL[i]] = i +end + +-- private log function, with support for formating a complex log message. +local function LOG_MSG(self, level, fmt, ...) + local f_type = type(fmt) + if f_type == 'string' then + if select('#', ...) > 0 then + return self:append(level, format(fmt, ...)) + else + -- only a single string, no formating needed. + return self:append(level, fmt) + end + elseif f_type == 'function' then + -- fmt should be a callable function which returns the message to log + return self:append(level, fmt(...)) + end + -- fmt is not a string and not a function, just call tostring() on it. + return self:append(level, tostring(fmt)) +end + +-- create the proxy functions for each log level. +local LEVEL_FUNCS = {} +for i=1,MAX_LEVELS do + local level = LEVEL[i] + LEVEL_FUNCS[i] = function(self, ...) + -- no level checking needed here, this function will only be called if it's level is active. + return LOG_MSG(self, level, ...) + end +end + +-- do nothing function for disabled levels. +local function disable_level() end + +-- improved assertion funciton. +local function assert(exp, ...) + -- if exp is true, we are finished so don't do any processing of the parameters + if exp then return exp, ... end + -- assertion failed, raise error + error(format(...), 2) +end + +------------------------------------------------------------------------------- +-- Creates a new logger object +-- @param append Function used by the logger to append a message with a +-- log-level to the log stream. +-- @return Table representing the new logger object. +------------------------------------------------------------------------------- +function new(append) + + if type(append) ~= "function" then + return nil, "Appender must be a function." + end + + local logger = {} + logger.append = append + + logger.setLevel = function (self, level) + local order = LEVEL[level] + assert(order, "undefined level `%s'", _tostring(level)) + self.level = level + self.level_order = order + -- enable/disable levels + for i=1,MAX_LEVELS do + local name = LEVEL[i]:lower() + if i >= order then + self[name] = LEVEL_FUNCS[i] + else + self[name] = disable_level + end + end + end + + -- generic log function. + logger.log = function (self, level, ...) + local order = LEVEL[level] + assert(order, "undefined level `%s'", _tostring(level)) + if order < self.level_order then + return + end + return LOG_MSG(self, level, ...) + end + + -- initialize log level. + logger:setLevel(DEBUG) + return logger +end + + +------------------------------------------------------------------------------- +-- Prepares the log message +------------------------------------------------------------------------------- +function prepareLogMsg(pattern, dt, level, message) + + local logMsg = pattern or "%date %level %message\n" + message = string.gsub(message, "%%", "%%%%") + logMsg = string.gsub(logMsg, "%%date", dt) + logMsg = string.gsub(logMsg, "%%level", level) + logMsg = string.gsub(logMsg, "%%message", message) + return logMsg +end + + +------------------------------------------------------------------------------- +-- Converts a Lua value to a string +-- +-- Converts Table fields in alphabetical order +------------------------------------------------------------------------------- +function tostring(value) + local str = '' + + if (type(value) ~= 'table') then + if (type(value) == 'string') then + str = string.format("%q", value) + else + str = _tostring(value) + end + else + local auxTable = {} + table.foreach(value, function(i, v) + if (tonumber(i) ~= i) then + table.insert(auxTable, i) + else + table.insert(auxTable, tostring(i)) + end + end) + table.sort(auxTable) + + str = str..'{' + local separator = "" + local entry = "" + table.foreachi (auxTable, function (i, fieldName) + if ((tonumber(fieldName)) and (tonumber(fieldName) > 0)) then + entry = tostring(value[tonumber(fieldName)]) + else + entry = fieldName.." = "..tostring(value[fieldName]) + end + str = str..separator..entry + separator = ", " + end) + str = str..'}' + end + return str +end diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/tablesample.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/tablesample.lua new file mode 100644 index 00000000..69ef7ea7 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/tablesample.lua @@ -0,0 +1,27 @@ +sample = {} + +local function getvalue (self, key, args) + print ("retrieving", key) + if (key == 'pippo') then + return function (p1,p2,p3,p4,p5,p6) return p2 end + end + return "__newindex "..key +end + +local function setvalue(self,key,value) + print ("setting",key,"to",value) + -- ... do some here with key / values +end + +local function oncall(self, key, args) + print("function calling...") + print(key) +end + +setmetatable(sample,{__index = getvalue, __newindex = setvalue, __call = oncall}) + +--sample['hello'] = 'world'; +--print(sample['hello']); +--print(sample(123)) + +print(sample:pippo(23)) \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test01.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test01.lua new file mode 100644 index 00000000..261ae37c --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test01.lua @@ -0,0 +1,18 @@ +io.write [[ +This is a normal text file +but now I'm start a Lua tag +]] + --here I can write simple Lua code + for i = 1,5 do + print("i = " .. tostring(i)); + end + +io.write [[ + +And now back to the simple text mode +Expressions are supported too. +Do you know what is the result of 5*5? +5*5 = ]]io.write( 5*5 ) +io.write [[ + +bye bye]] \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test04.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test04.lua new file mode 100644 index 00000000..f1dca35d --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test04.lua @@ -0,0 +1,9 @@ +a = { + nome = "Daniele", + cognome = "Teti", + eta = 32 + } + +for k,v in pairs(a) do + print(k..'='..v) +end diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test1.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test1.lua new file mode 100644 index 00000000..687eec44 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test1.lua @@ -0,0 +1,2 @@ +days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} +print(days[3]); \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/testConsole.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/testConsole.lua new file mode 100644 index 00000000..a86f71c7 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/testConsole.lua @@ -0,0 +1,9 @@ +require"logging.console" + +local logger = logging.console() + +logger:info("logging.console test") +logger:debug("debugging...") +logger:error("error!") +logger:debug("string with %4") +print("Console Logging OK") \ No newline at end of file diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/testFile.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/testFile.lua new file mode 100644 index 00000000..1a2b111c --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/testFile.lua @@ -0,0 +1,6 @@ +require "logging.file" +local logger = logging.file("__TEST%s.log", "%Y-%m-%d") +logger:info("logging.file test") +logger:debug("debugging...") +logger:error("error!") +logger:info({id = "1"}) diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_01.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_01.lua new file mode 100644 index 00000000..3b24fa28 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_01.lua @@ -0,0 +1,5 @@ +local x = 1+2+3; +local s = "Hello World"; +if (x > 2) then + print(s); +end diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_02.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_02.lua new file mode 100644 index 00000000..7917c789 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_02.lua @@ -0,0 +1,23 @@ +require "lua_taival.datasets" + +local s = open_dataset(people); +s.first(); +local f = io.open("test_02.txt", "w") +while not s.eof() do + f:write(s.get('first_name').." "..s.get('last_name').." "..s.get('born_date').." "..s.get("is_male").."\n") + s.movenext() +end; +s.close() + +f:write(tostring(s.is_open())) +s.open() +f:write(tostring(s.is_open())) +s.movenext() +f:write(tostring(s.is_open())) +s.first() +f:write(tostring(s.is_open())) +s.movenext() +f:write(tostring(s.is_open())) +s.close() +f:write(tostring(s.is_open())) +f:close() diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_03.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_03.lua new file mode 100644 index 00000000..464727b8 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_03.lua @@ -0,0 +1,26 @@ +require "lua_taival.delphiobjects" +require "logging.file" + +logger = logging.file("test_03_TEST.log") + +local s = connect_to_delphi_object(person); +s.FirstName = "Daniele"; +s.LastName = "Teti"; +s.Age = 30; + + + +s.BecomeOlder(2); +first_name = s.FirstName; +last_name = s.LastName; +full_name = s.GetFullName('Mr.'); +age = s.Age; + + +--reading property +local name = s.LastName + +--writing a property +s.LastName = "Teti" --you can write to a property in this way + + diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_04.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_04.lua new file mode 100644 index 00000000..59babc91 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_04.lua @@ -0,0 +1,10 @@ +require "lua_taival.delphiobjects" +require "logging.file" +logger = logging.file("test_04_TEST_%s.log", "%Y-%m-%d") + +local sl = connect_to_delphi_object(stringlist); + +sl.Add("two"); +sl.Add("three"); +sl.Add("four"); +logger:debug(sl.Text); diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_05.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_05.lua new file mode 100644 index 00000000..2379d39e --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_05.lua @@ -0,0 +1,7 @@ +require "lua_taival.delphiobjects" +require "logging.file" +logger = logging.file("test_05_TEST_%s.log", "%Y-%m-%d") + +local sl = connect_to_delphi_object(stringlist); +sl.Text = "Daniele Teti" +logger:debug(sl.Text); diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_06.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_06.lua new file mode 100644 index 00000000..91bf2816 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_06.lua @@ -0,0 +1,8 @@ +require "lua_taival.delphiobjects" +require "logging.file" +logger = logging.file("test_06_TEST.log") + +local sl = create_delphi_object('System.Classes.TStringList') +sl.Text = "Daniele Teti" +logger:debug('Ecco il contenuto della TStringList: '..sl.Text); +sl.Free(); diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_07.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_07.lua new file mode 100644 index 00000000..bf524b1e --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_07.lua @@ -0,0 +1,6 @@ +require "lua_taival.delphiobjects" +require "logging.file" +logger = logging.file("test_07_TEST_%s.log", "%Y-%m-%d") + +--this should raise an exception +local fs = create_delphi_object('System.Classes.TFileStream'); diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_08.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_08.lua new file mode 100644 index 00000000..591ea320 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_08.lua @@ -0,0 +1,3 @@ +function myfunc(a,b,c) + return a..b..c +end diff --git a/samples/serversideviews_lua/lua4delphi/samples/bin/test_mydirtytest.lua b/samples/serversideviews_lua/lua4delphi/samples/bin/test_mydirtytest.lua new file mode 100644 index 00000000..2ad020c8 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/bin/test_mydirtytest.lua @@ -0,0 +1,5 @@ +local sl = TStringList.new() +sl:add('Hello World') +--sl.add('Hello World2') + + diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dpr b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dpr new file mode 100644 index 00000000..0316deab --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dpr @@ -0,0 +1,21 @@ +program LuaPlayground; + +uses + Vcl.Forms, + Unit11 in 'Unit11.pas' {MainForm}, + LuaBind.Intf in '..\..\LuaBind.Intf.pas', + LuaBind in '..\..\LuaBind.pas', + LuaBind.CustomType.DataSet in '..\..\LuaBind.CustomType.DataSet.pas', + LuaBind.DelphiObjects in '..\..\LuaBind.DelphiObjects.pas'; + +{$R *.res} + + +begin + ReportMemoryLeaksOnShutdown := True; + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TMainForm, MainForm); + Application.Run; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dproj b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dproj new file mode 100644 index 00000000..6a2d1e47 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaPlayground.dproj @@ -0,0 +1,989 @@ + + + {F2D71A9C-D7E4-4B13-9AB9-F8ED3349D646} + 19.3 + VCL + LuaPlayground.dpr + True + Debug + Win32 + 1 + Application + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;DBXOracleDriver;dsnap;DBXInformixDriver;IndyCore;fmxase;DBXFirebirdDriver;inet;fmxobj;inetdbxpress;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;IPIndyImpl;$(DCC_UsePackage) + $(BDS)\bin\delphi_PROJECTICON.ico + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + LuaPlayground + + + OpenWirePkgD16;vcldbx;frx16;TeeDB;Rave100VCL;vclib;Tee;inetdbbde;DBXOdbcDriver;DBXSybaseASEDriver;ibxpress;svnui;vclimg;OpenWireLabPkgD16;intrawebdb_120_160;fmi;frxDB16;fs16;vclactnband;FMXTee;vcldb;TeeUI;bindcompvcl;vcldsnap;SynEdit_RXE2;vclie;vcltouch;Intraweb_120_160;DBXDb2Driver;websnap;dwsLibRuntime;vclribbon;VclSmp;fsDB16;frxe16;vcl;DataSnapConnectors;UIBD16Win32R;CodeSiteExpressPkg;CloudService;DBXMSSQLDriver;FmxTeeUI;dsnapcon;RlxPackage;DataSnapServerConnectionMonitoring;vclx;webdsnap;svn;bdertl;adortl;$(DCC_UsePackage) + true + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + $(BDS)\bin\default_app.manifest + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + true + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + DBXOdbcDriver;DBXSybaseASEDriver;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;SynEdit_RXE2;vclie;vcltouch;DBXDb2Driver;websnap;VclSmp;vcl;DataSnapConnectors;DBXMSSQLDriver;dsnapcon;vclx;webdsnap;$(DCC_UsePackage) + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + DEBUG;$(DCC_Define) + false + true + true + true + + + false + Debug + ..\bin + true + 1033 + true + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + +
MainForm
+ dfm +
+ + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + LuaPlayground.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + LuaPlayground.exe + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + True + False + + + C:\Users\Daniele\Desktop\luawrapper\unittests\LuaTestTests.dproj + + + 12 + + + + +
diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/LuaWrapper.pas b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaWrapper.pas new file mode 100644 index 00000000..afa885f3 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/playground/LuaWrapper.pas @@ -0,0 +1,401 @@ +unit LuaWrapper; + +interface + +uses dorLua, + System.Classes, + System.SysUtils, + System.Rtti; + +type + ELuaException = class(Exception) + + end; + + ILuaValue = interface + ['{8621BAD3-B847-4176-937F-2CD016BBE13E}'] + /// /// + function IsNil: boolean; + function IsNumber: boolean; + function IsInteger: boolean; + function IsString: boolean; + function IsBoolean: boolean; + function IsLightUserData: boolean; + /// /// + function GetAsNumber: Double; + function GetAsInteger: Integer; + function GetAsString: AnsiString; + function GetAsBoolean: boolean; + function GetAsLightUserData: Pointer; + end; + + TLuaValueType = (lvtNil, lvtNumber, lvtInteger, lvtString, lvtBoolean, lvtLightUserData, + lvtTable, lvtFunction, lvtUserData, lvtThread); + + TLuaValue = class(TInterfacedObject, ILuaValue) + strict private + FLuaValueType: TLuaValueType; + strict + private + + protected + /// /// + function IsNil: boolean; + function IsNumber: boolean; + function IsInteger: boolean; + function IsString: boolean; + function IsBoolean: boolean; + function IsLightUserData: boolean; + /// /// + function GetAsNumber: Double; + function GetAsInteger: Integer; + function GetAsString: AnsiString; + function GetAsBoolean: boolean; + function GetAsLightUserData: Pointer; + private + procedure CheckType(LuaValueType: TLuaValueType); + protected + FValue: TValue; + constructor Create(LuaState: Plua_State; StackIndex: Integer); + { todo } + function GetAsLuaTable(LuaState: Plua_State; StackIndex: Integer): TValue; + public + class function GetLuaValueType(LuaState: Plua_State; StackIndex: Integer): TLuaValueType; + end; + + TLuaEngine = class + strict protected + LState: Plua_State; + public + constructor Create; overload; virtual; + constructor Create(const AScript: String); overload; virtual; + destructor Destroy; override; + procedure LoadScript(const AScript: AnsiString); overload; + procedure LoadScript(const AStream: TStream; AOwnStream: boolean = true); overload; + procedure LoadFromFile(const AFileName: String); + procedure Execute; + + // PUSH methods for simple types + function DeclareGlobalNil(AName: AnsiString): TLuaEngine; + function DeclareGlobalNumber(AName: AnsiString; AValue: Double): TLuaEngine; + function DeclareGlobalInteger(AName: AnsiString; AValue: Integer): TLuaEngine; + function DeclareGlobalString(AName: AnsiString; AValue: AnsiString): TLuaEngine; + function DeclareGlobalBoolean(AName: AnsiString; AValue: boolean): TLuaEngine; + function DeclareGlobalLightUserData(AName: AnsiString; AValue: Pointer): TLuaEngine; + + // GET methods for simple types + function GetGlobal(AName: AnsiString): ILuaValue; + end; + +implementation + +{ TLuaEngine } + +constructor TLuaEngine.Create; +begin + inherited Create; + LState := lua_open; + if not assigned(LState) then + raise ELuaException.Create('Cannot initialize Lua'); + luaL_openlibs(LState); +end; + +constructor TLuaEngine.Create(const AScript: String); +begin + Create; + LoadScript(AScript); +end; + +function TLuaEngine.DeclareGlobalBoolean(AName: AnsiString; AValue: boolean): TLuaEngine; +var + b: Integer; +begin + if AValue then + b := 1 + else + b := 0; + lua_pushboolean(LState, b); + lua_setglobal(LState, PAnsiChar(AName)); +end; + +function TLuaEngine.DeclareGlobalInteger(AName: AnsiString; AValue: Integer): TLuaEngine; +begin + lua_pushinteger(LState, AValue); + lua_setglobal(LState, PAnsiChar(AName)); +end; + +function TLuaEngine.DeclareGlobalLightUserData(AName: AnsiString; AValue: Pointer): TLuaEngine; +begin + lua_pushlightuserdata(LState, AValue); + lua_setglobal(LState, PAnsiChar(AName)); +end; + +function TLuaEngine.DeclareGlobalNil(AName: AnsiString): TLuaEngine; +begin + lua_pushnil(LState); + lua_setglobal(LState, PAnsiChar(AName)); +end; + +function TLuaEngine.DeclareGlobalNumber(AName: AnsiString; AValue: Double): TLuaEngine; +begin + lua_pushnumber(LState, AValue); + lua_setglobal(LState, PAnsiChar(AName)); +end; + +function TLuaEngine.DeclareGlobalString(AName: AnsiString; AValue: AnsiString): TLuaEngine; +begin + lua_pushstring(LState, PAnsiChar(AValue)); + lua_setglobal(LState, PAnsiChar(AName)); +end; + +destructor TLuaEngine.Destroy; +begin + lua_close(LState); + inherited; +end; + +procedure TLuaEngine.Execute; +var + err: PAnsiChar; + r: Integer; +begin + r := lua_pcall(LState, 0, 0, 0); + case r of + // success + 0: + begin + lua_pop(LState, lua_gettop(LState)); + end; + // a runtime error. + LUA_ERRRUN: + begin + err := lua_tostring(LState, -1); + raise ELuaException.CreateFmt('Runtime error [%s]', [err]); + lua_pop(LState, 1); + end; + // memory allocation error. For such errors, Lua does not call the error handler function. + LUA_ERRMEM: + begin + err := lua_tostring(LState, -1); + raise ELuaException.CreateFmt('Memory allocation error [%s]', [err]); + lua_pop(LState, 1); + end; + // error while running the error handler function. + LUA_ERRERR: + begin + err := lua_tostring(LState, -1); + raise ELuaException.CreateFmt('Error while running the error handler function [%s]', [err]); + lua_pop(LState, 1); + end; + else + begin + err := lua_tostring(LState, -1); + raise ELuaException.CreateFmt('Unknown Error [%s]', [err]); + lua_pop(LState, 1); + end; + end; +end; + +function TLuaEngine.GetGlobal(AName: AnsiString): ILuaValue; +begin + lua_getglobal(LState, PAnsiChar(AName)); + Result := TLuaValue.Create(LState, -1); +end; + +procedure TLuaEngine.LoadFromFile(const AFileName: String); +var + err: PAnsiChar; +begin + if luaL_loadfile(LState, PAnsiChar(AFileName)) <> 0 then + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.Create(err); + end; +end; + +procedure TLuaEngine.LoadScript(const AStream: TStream; AOwnStream: boolean); +var + sr: TStreamReader; + s: string; +begin + sr := TStreamReader.Create(AStream); + try + if AOwnStream then + sr.OwnStream; + s := sr.ReadToEnd; + LoadScript(s); + finally + sr.Free; + end; +end; + +procedure TLuaEngine.LoadScript(const AScript: AnsiString); +var + err: PAnsiChar; +begin + if luaL_loadstring(LState, + PAnsiChar(AScript)) <> 0 then + begin + err := lua_tostring(LState, -1); + lua_pop(LState, 1); + raise ELuaException.Create(err); + end; +end; + +{ TLuaValue } + +constructor TLuaValue.Create(LuaState: Plua_State; StackIndex: Integer); +var + a: AnsiString; + _lua_CFunction: lua_CFunction; + _pluastate: Plua_State; +begin + inherited Create; + FLuaValueType := GetLuaValueType(LuaState, StackIndex); + + case FLuaValueType of + lvtNil: + FValue := nil; + + lvtNumber: + FValue := lua_tonumber(LuaState, StackIndex); + + lvtInteger: + FValue := lua_tointeger(LuaState, StackIndex); + + lvtString: + begin + a := lua_tostring(LuaState, StackIndex); + FValue := a; + end; + + lvtBoolean: + FValue := lua_toboolean(LuaState, StackIndex) = 1; + + lvtLightUserData: + FValue := lua_topointer(LuaState, StackIndex); + + lvtTable: + begin + FValue := GetAsLuaTable(LuaState, StackIndex); + end; + + lvtFunction: + begin + _lua_CFunction := lua_tocfunction(LuaState, StackIndex); + FValue := nil; { todo } + end; + + lvtUserData: + FValue := lua_touserdata(LuaState, StackIndex); + + lvtThread: + begin + _pluastate := lua_tothread(LuaState, StackIndex); + FValue := nil; { todo } + end; + end; + +end; + +class function TLuaValue.GetLuaValueType(LuaState: Plua_State; StackIndex: Integer): + TLuaValueType; +begin + case lua_type(LuaState, StackIndex) of + LUA_TNIL: + Result := lvtNil; + LUA_TNUMBER: + Result := lvtNumber; + LUA_TBOOLEAN: + Result := lvtBoolean; + LUA_TSTRING: + Result := lvtString; + LUA_TTABLE: + Result := lvtTable; + LUA_TFUNCTION: + Result := lvtFunction; + LUA_TUSERDATA: + Result := lvtUserData; + LUA_TTHREAD: + Result := lvtThread; + LUA_TLIGHTUSERDATA: + Result := lvtLightUserData; + LUA_TNONE: + raise ELuaException.Create('Invalid stack index location'); + end; +end; + +procedure TLuaValue.CheckType(LuaValueType: TLuaValueType); +begin + if FLuaValueType <> LuaValueType then + raise ELuaException.Create('Cannot access value as ' + inttostr(Integer(LuaValueType))); +end; + +function TLuaValue.GetAsBoolean: + boolean; +begin + CheckType(lvtBoolean); + Result := FValue.AsBoolean; +end; + +function TLuaValue.GetAsInteger: Integer; +begin + CheckType(lvtInteger); + Result := FValue.AsInteger; +end; + +function TLuaValue.GetAsLightUserData: Pointer; +begin + CheckType(lvtLightUserData); + Result := FValue.AsType; +end; + +function TLuaValue.GetAsLuaTable(LuaState: Plua_State; StackIndex: Integer): TValue; +begin + { todo } +end; + +function TLuaValue.GetAsNumber: Double; +begin + CheckType(lvtNumber); + Result := FValue.AsExtended; +end; + +function TLuaValue.GetAsString: AnsiString; +begin + CheckType(lvtString); + Result := FValue.AsString; +end; + +function TLuaValue.IsBoolean: boolean; +begin + Result := FLuaValueType = lvtBoolean; +end; + +function TLuaValue.IsInteger: boolean; +begin + Result := FLuaValueType = lvtInteger; +end; + +function TLuaValue.IsLightUserData: boolean; +begin + Result := FLuaValueType = lvtLightUserData; +end; + +function TLuaValue.IsNil: boolean; +begin + Result := FLuaValueType = lvtNil; +end; + +function TLuaValue.IsNumber: boolean; +begin + Result := FLuaValueType = lvtNumber; +end; + +function TLuaValue.IsString: boolean; +begin + Result := FLuaValueType = lvtString; +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.dfm b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.dfm new file mode 100644 index 00000000..1ed60482 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.dfm @@ -0,0 +1,52 @@ +object MainForm: TMainForm + Left = 0 + Top = 0 + Caption = 'PlaygroundForm' + ClientHeight = 404 + ClientWidth = 533 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object Button1: TButton + Left = 8 + Top = 8 + Width = 145 + Height = 49 + Caption = 'lua_pcall' + TabOrder = 0 + OnClick = Button1Click + end + object Button2: TButton + Left = 159 + Top = 8 + Width = 179 + Height = 49 + Caption = 'Load Config File' + TabOrder = 1 + OnClick = Button2Click + end + object Button3: TButton + Left = 8 + Top = 63 + Width = 515 + Height = 50 + Caption = 'push_object_properties' + TabOrder = 2 + OnClick = Button3Click + end + object Button4: TButton + Left = 344 + Top = 8 + Width = 179 + Height = 49 + Caption = 'GetGlobal' + TabOrder = 3 + OnClick = Button4Click + end +end diff --git a/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.pas b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.pas new file mode 100644 index 00000000..90d14cd0 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/samples/playground/MainFormU.pas @@ -0,0 +1,495 @@ +unit MainFormU; + +interface + +uses + Winapi.Windows, + Winapi.Messages, + System.SysUtils, + System.Variants, + System.Classes, + Vcl.Graphics, + Vcl.Controls, + Vcl.Forms, + Vcl.Dialogs, + Vcl.StdCtrls, + Data.DB, + Datasnap.DBClient, + Vcl.ExtCtrls, + Vcl.DBCtrls, + Vcl.Grids, + Vcl.DBGrids; + +type + TMainForm = class(TForm) + Button1: TButton; + Button2: TButton; + Button3: TButton; + Button4: TButton; + procedure Button1Click(Sender: TObject); + procedure Button2Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure Button4Click(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure Button5Click(Sender: TObject); + + private + { Private declarations } + public + { Public declarations } + end; + + TPersona = class + private + FAge : Integer; + FLastName : string; + FFirstName: string; + FBornDate : TDateTime; + FChild : TPersona; + procedure SetAge(const Value: Integer); + procedure SetFirstName(const Value: string); + procedure SetLastName(const Value: string); + procedure SetBornDate(const Value: TDateTime); + procedure SetChild(const Value: TPersona); + + public + class function NewPersona: TPersona; + property FirstName: string read FFirstName write SetFirstName; + property LastName: string read FLastName write SetLastName; + property Age: Integer read FAge write SetAge; + property BornDate: TDateTime read FBornDate write SetBornDate; + property Child: TPersona read FChild write SetChild; + end; + +var + MainForm: TMainForm; + +implementation + +uses + rtti, + System.TypInfo, + LuaBind.Intf, + LuaBind; + +{$R *.dfm} + + +procedure TMainForm.Button1Click(Sender: TObject); +var + state: Plua_State; +begin + state := lua_open; + if not assigned(state) then + raise Exception.Create('Cannot initialize Lua'); + try + luaL_openlibs(state); + if luaL_loadstring(state, + 'days = {"Sunday", "Monday", "Tuesday", "Wednesday"}; ' + + 'print(days[2]);') = 0 then + begin + if lua_pcall(state, 0, 1, 0) <> 0 then + begin + ShowMessage(lua_tostring(state, - 1)); + lua_pop(state, 1); + end + else + begin + lua_pop(state, lua_gettop(state)); + end; + end + else + begin + ShowMessage(lua_tostring(state, - 1)); + lua_pop(state, 1); + end; + finally + lua_close(state); + end; +end; + +function MyFunctionForLua(L: Plua_State): Integer; cdecl; +var + v: pansichar; + s: ansistring; +begin + s := uppercase(lua_tostring(L, 1)); + lua_pushstring(L, pansichar(s)); + Result := 1; // * number of results * / +end; + +function myfullname(L: Plua_State): Integer; cdecl; +var + v: pansichar; + s: ansistring; +begin + assert(lua_istable(L, - 1)); + lua_getfield(L, - 1, pansichar('nome')); + s := lua_tostring(L, - 1); + lua_pushstring(L, pansichar(s)); + Result := 1; // * number of results * / +end; + +function _setcaption(L: Plua_State): Integer; cdecl; +var + form : TForm; + newcaption: ansistring; +begin + assert(lua_type(L, - 1) = LUA_TSTRING); + assert(lua_type(L, - 2) = LUA_TLIGHTUSERDATA); + + newcaption := lua_tostring(L, - 1); + lua_pop(L, 1); + + form := TForm(lua_topointer(L, - 1)); + lua_pop(L, 1); + + form.Caption := newcaption; + Result := 0; +end; + +function doSomethingOnDelphiObject(L: Plua_State): Integer; cdecl; +var + v : pansichar; + s : ansistring; + p : Pointer; + form: TMainForm; +begin + + // TFileStream.Create('', fmCreate); + + assert(lua_islightuserdata(L, - 1)); + // lua_pop(L, ); + p := lua_topointer(L, - 1); + lua_pop(L, 1); + form := TMainForm(p); + form.Caption := 'Cambiato da Lua'; + + // lua_getfield(L, -1, pansichar('nome')); + // s := lua_tostring(L, -1); + // lua_pushstring(L, pansichar(s)); + // + Result := 0; // * number of results * / +end; + +procedure SetSomeTables(L: Plua_State); +begin + lua_newtable(L); + lua_pushstring(L, 'nome'); + lua_pushstring(L, 'Daniele'); + lua_settable(L, - 3); + + lua_pushstring(L, 'cognome'); + lua_pushstring(L, 'Teti'); + lua_settable(L, - 3); + + lua_pushstring(L, 'eta'); + lua_pushnumber(L, 3); + lua_settable(L, - 3); + + lua_pushstring(L, 'fullname'); + lua_pushcfunction(L, @myfullname); + lua_settable(L, - 3); + + lua_setglobal(L, 'daniele'); +end; + +// procedure SetSomeTables(L: Plua_State); +// begin +// lua_newtable(L); +// lua_pushstring(L, 'nome'); +// lua_pushstring(L, 'Daniele'); +// lua_pushstring(L, 'cognome'); +// lua_pushnumber(L, 2); +// lua_pushstring(L, 'eta'); +// lua_pushnumber(L, 3); +// lua_pushstring(L, 'fullname'); +// lua_pushcfunction(L, @myfullname); +// lua_settable(L, -9); +// lua_settable(L, -7); +// lua_settable(L, -5); +// lua_settable(L, -3); +// lua_setglobal(L, 'daniele'); +// end; + +procedure SetSomeVariables(L: Plua_State); +begin + lua_pushnumber(L, 11); + lua_pushnumber(L, 22); + lua_pushnumber(L, 33); + lua_setglobal(L, 'x3'); + lua_setglobal(L, 'x2'); + lua_setglobal(L, 'x1'); +end; + +function Load(filename: ansistring; out AWidth: Integer; + out AHeight: Integer): string; +var + L : Plua_State; + AStringa: string; +begin + L := lua_open(); + luaL_openlibs(L); + // luaopen_base(L); + // luaopen_io(L); + // luaopen_string(L); + // luaopen_math(L); + + if (luaL_loadfile(L, pansichar(filename)) > 0) then + begin + Exit('Cannot run configuration file ' + lua_tostring(L, - 1)); + end; + + SetSomeVariables(L); + SetSomeTables(L); + + lua_pushcfunction(L, @MyFunctionForLua); + lua_setglobal(L, 'delphiuppercase'); + + lua_pushcfunction(L, @doSomethingOnDelphiObject); + lua_setglobal(L, 'dosomething'); + + lua_pushcfunction(L, @_setcaption); + lua_setglobal(L, '_setcaption'); + + lua_pushlightuserdata(L, MainForm); + lua_setglobal(L, 'form'); + + if lua_pcall(L, 0, 0, 0) > 0 then + begin + Exit('Cannot exec configuration file ' + lua_tostring(L, - 1)); + end; + + lua_getglobal(L, 'width'); + lua_getglobal(L, 'height'); + lua_getglobal(L, 'stringa'); + + if (lua_isnumber(L, - 3) = 0) then + Exit('Width should be a number'); + + if (lua_isnumber(L, - 2) = 0) then + Exit('Height should be a number'); + + if (lua_isstring(L, - 1) = 0) then + Exit('stringa should be a string'); + + AWidth := lua_tointeger(L, - 3); + AHeight := lua_tointeger(L, - 2); + AStringa := lua_tostring(L, - 1); + lua_close(L); + Result := Format('Width: %d, Height: %d, Stringa: %s', + [AWidth, AHeight, AStringa]); +end; + +procedure TMainForm.Button2Click(Sender: TObject); +var + w: Integer; + h: Integer; +begin + ShowMessage(Load('config.lua', w, h)); +end; + +procedure push_object_properties(L: Plua_State; AObject: TObject; + AName: string); +var + prop : TRttiProperty; + ctx : TRttiContext; + properties: TArray; + k : ansistring; + Value : TValue; + v : ansistring; +begin + ctx := TRttiContext.Create; + try + lua_newtable(L); + properties := ctx.GetType(AObject.ClassType).GetProperties; + for prop in properties do + begin + k := prop.Name; + lua_pushstring(L, pansichar(k)); + Value := prop.GetValue(AObject); + if Value.TypeInfo^.Kind in [tkString, tkUString] then + begin + v := Value.AsString; + lua_pushstring(L, pansichar(v)); + end + else if Value.TypeInfo^.Kind = tkInteger then + begin + lua_pushnumber(L, Value.AsInteger); + end + else if Value.TypeInfo^.Kind = tkFloat then + begin + lua_pushnumber(L, Value.AsExtended); + end + else if Value.TypeInfo^.Kind = tkClass then + begin + if Value.IsEmpty then + lua_pushnil(L) + else + push_object_properties(L, Value.AsObject, ''); + end; + + lua_settable(L, - 3); + end; + finally + ctx.Free; + end; +end; + +procedure push_table(L: Plua_State; Keys: array of ansistring; + Values: array of ansistring); +var + key : TObject; + I : Integer; + k : ansistring; + v : ansistring; + pvalue, pkey: pansichar; + le : Cardinal; +begin + // lua_newtable(L); + // pkey := GetMemory(Length('firstname') + 1); + // pkey := StrCopy(pkey, pansichar('firstname')); + // lua_pushstring(L, pkey); + // //lua_pushstring(L, 'firstname'); + // lua_pushstring(L, 'Daniele'); + // lua_settable(L, -3); + // lua_pushstring(L, 'lastname'); + // lua_pushstring(L, 'Teti'); + // lua_settable(L, -3); + + lua_newtable(L); + for I := 0 to high(Keys) do + begin + k := Keys[I]; + v := Values[I]; + lua_pushstring(L, pansichar(k)); + lua_pushstring(L, pansichar(v)); + lua_settable(L, - 3); + end; + + + // k := Keys[I]; + // pkey := GetMemory(Length(k) + 1); + // ZeroMemory(pkey, Length(k) + 1); + // MoveMemory(pkey, pansichar(k), Length(k)); + /// / pkey := StrPCopy(pkey, pansichar(k)); + // + // v := Values[I]; + // pvalue := GetMemory(Length(v) + 1); + // pvalue := StrCopy(pvalue, pansichar(v)); + // + // lua_pushstring(L, pkey); + // lua_pushstring(L, pvalue); + // lua_settable(L, -3); + +end; + +procedure TMainForm.Button3Click(Sender: TObject); +var + L : Plua_State; + persona: TPersona; +begin + persona := TPersona.Create; + try + persona.FirstName := 'Daniele'; + persona.LastName := 'Teti'; + persona.Age := 32; + persona.BornDate := date; + persona.Child := TPersona.NewPersona; + + L := lua_open; + try + luaL_openlibs(L); + if luaL_loadfile(L, 'test01.html') > 0 then + raise Exception.Create('Cannot run configuration file ' + + lua_tostring(L, - 1)); + + // push_table(L, ['firstname', 'lastname'], ['Daniele', 'Teti']); + push_object_properties(L, persona, 'persona'); + lua_setglobal(L, 'persona'); + if lua_pcall(L, 0, 0, 0) > 0 then + begin + raise Exception.Create('Cannot exec configuration file ' + + lua_tostring(L, - 1)); + end; + lua_getglobal(L, 'p'); + ShowMessage(lua_tostring(L, - 1)); + finally + lua_close(L); + end; + finally + persona.Child.Free; + persona.Free; + end; +end; + +procedure TMainForm.Button4Click(Sender: TObject); +var + lua: TLuaEngine; + v : ILuaValue; +begin + lua := TLuaEngine.Create; + try + lua.LoadScript( + 'local z = y + 2;' + sLineBreak + + 'x = y + 1 + z;'); + lua.DeclareGlobalInteger('y', 4); + lua.Execute; + v := lua.GetGlobal('x'); + if v.IsNumber then + ShowMessage(FloatToStr(v.GetAsNumber)); + finally + lua.Free; + end; +end; + +procedure TMainForm.Button5Click(Sender: TObject); +begin + // ClientDataSet1.SaveToFile(ClientDataSet1.filename); + // ClientDataSet1.Close; +end; + +procedure TMainForm.FormCreate(Sender: TObject); +begin + // ClientDataSet1.Close; + // ClientDataSet1.filename := '..\..\..\unittests\win32\debug\samplecds.xml'; + // ClientDataSet1.Open; +end; + +{ TPersona } + +class function TPersona.NewPersona: TPersona; +begin + Result := TPersona.Create; + Result.FirstName := 'Mattia'; + Result.LastName := 'Teti'; + Result.Age := 1; + Result.BornDate := EncodeDate(2011, 11, 17); +end; + +procedure TPersona.SetAge(const Value: Integer); +begin + FAge := Value; +end; + +procedure TPersona.SetBornDate(const Value: TDateTime); +begin + FBornDate := Value; +end; + +procedure TPersona.SetChild(const Value: TPersona); +begin + FChild := Value; +end; + +procedure TPersona.SetFirstName(const Value: string); +begin + FFirstName := Value; +end; + +procedure TPersona.SetLastName(const Value: string); +begin + FLastName := Value; +end; + +end. diff --git a/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dpr b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dpr new file mode 100644 index 00000000..9185bf10 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dpr @@ -0,0 +1,27 @@ +program LuaBindingUnitTests; + +{$IFDEF CONSOLE_TESTRUNNER} +{$APPTYPE CONSOLE} +{$ENDIF} + + +uses + DUnitTestRunner, + TestLuaWrapper in 'TestLuaWrapper.pas', + TestObjects in 'TestObjects.pas', + TestLuaEmbeddedTextFilter in 'TestLuaEmbeddedTextFilter.pas', + LuaBind.Filters.Text in '..\LuaBind.Filters.Text.pas', + LuaBind.Intf in '..\LuaBind.Intf.pas', + LuaBind.CustomType.DataSet in '..\LuaBind.CustomType.DataSet.pas', + LuaBind.CustomType.PODO in '..\LuaBind.CustomType.PODO.pas', + LuaBind.CustomType.UserType in '..\LuaBind.CustomType.UserType.pas', + LuaBind in '..\LuaBind.pas', + LuaBind.DelphiObjects in '..\LuaBind.DelphiObjects.pas'; + +{$R *.RES} + + +begin + ReportMemoryLeaksOnShutdown := True; + DUnitTestRunner.RunRegisteredTests; +end. diff --git a/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dproj b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dproj new file mode 100644 index 00000000..e5eceb33 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/unittests/LuaBindingUnitTests.dproj @@ -0,0 +1,971 @@ + + + {617B701F-53AB-42BC-8140-9BEC89FB3469} + 19.3 + None + True + Debug + Win32 + 1 + Console + LuaBindingUnitTests.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + LuaBindingUnitTests + $(BDS)\bin\delphi_PROJECTICNS.icns + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath) + _CONSOLE_TESTRUNNER;$(DCC_Define) + System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) + fmx;IndySystem;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;DBXOracleDriver;CustomIPTransport;AureliusXE2;dsnap;IndyCore;fmxase;inetdbxpress;IPIndyImpl;bindcompfmx;rtl;dbrtl;DbxClientDriver;bindcomp;inetdb;xmlrtl;ibxpress;IndyProtocols;DBXMySQLDriver;bindengine;soaprtl;DBXInformixDriver;DBXFirebirdDriver;inet;fmxobj;LKSL;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;$(DCC_UsePackage) + . + .\$(Platform)\$(Config) + + + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + Debug + true + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + true + true + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + true + Base + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + true + true + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png + + + JvGlobus;JvMM;JvDlgs;JvCrypt;TeeDB;Rave100VCL;vclib;inetdbbde;DBXSybaseASEDriver;vclimg;DataBindingsVCL160;fmi;vcldb;vcldsnap;dac160;unidacvcl160;DBXDb2Driver;Intraweb_120_160;dwsLibRuntime;JvCore;vclribbon;frxe16;vcl;CloudService;DBXMSSQLDriver;CodeSiteExpressPkg;unidac160;FmxTeeUI;JvAppFrm;JvRuntimeDesign;webdsnap;JclDeveloperTools;adortl;JvWizards;SimpleGraphPackage;NewAC;OpenWirePkgD16;vcldbx;frx16;DotNet4Delphi_XE2;crcontrols160;JclContainers;Tee;DataBindings;DBXOdbcDriver;JvCmp;JvSystem;svnui;adgrmxe2;JvControls;frxDB16;intrawebdb_120_160;fs16;vclactnband;FMXTee;TeeUI;bindcompvcl;JvStdCtrls;JvCustom;Jcl;vclie;vcltouch;dacvcl160;websnap;VclSmp;fsDB16;DataSnapConnectors;RlxPackage;dsnapcon;JclVcl;JvPascalInterpreter;vclx;Lua4Delphi;svn;bdertl;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName);FileDescription=$(MSBuildProjectName);ProductName=$(MSBuildProjectName) + ..\samples\bin + (None) + + + vclib;DBXSybaseASEDriver;vclimg;vcldb;vcldsnap;DBXDb2Driver;vcl;DBXMSSQLDriver;webdsnap;adortl;DBXOdbcDriver;adgrmxe2;vclactnband;bindcompvcl;vclie;vcltouch;websnap;VclSmp;DataSnapConnectors;dsnapcon;vclx;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + false + true + true + true + + + 3 + None + 1033 + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + + + + + + + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + + + + Delphi.Personality.12 + + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + LuaBindingUnitTests.dpr + + + + + + + true + + + + + true + + + + + true + + + + + 1 + + + 0 + + + + + classes + 64 + + + classes + 64 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 1 + .framework + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + + + + False + False + False + True + False + + + DUnit / Delphi Win32 + GUI + C:\Users\Daniele\Desktop\luawrapper\mytest\LuaTest.dproj + + + + 12 + + + + + diff --git a/samples/serversideviews_lua/lua4delphi/unittests/TestLuaEmbeddedTextFilter.pas b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaEmbeddedTextFilter.pas new file mode 100644 index 00000000..686b897a --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaEmbeddedTextFilter.pas @@ -0,0 +1,168 @@ +unit TestLuaEmbeddedTextFilter; +{ + + Delphi DUnit Test Case + ---------------------- + This unit contains a skeleton test case class generated by the Test Case Wizard. + Modify the generated code to correctly setup and call the methods from the unit + being tested. + +} + +interface + +uses + TestFramework, + System.Classes, + TestLuaWrapper, + System.SysUtils, + LuaBind, + LuaBind.Intf, + System.Rtti; + +type + TTestEmbeddedTextFilter = class(TTestCase) + strict private + FLuaEngine: TLuaEngine; + + public + procedure SetUp; override; + procedure TearDown; override; + + published + procedure TestDoAllTests; + procedure TestHelperExecAndGet01; + procedure TestHelperExecAndGetMultiThread; + end; + +implementation + +uses + System.IOUtils, + LuaBind.Filters.Text, + System.Generics.collections, + System.Types; + +{ TTestEmbeddedTextFilter } + +procedure TTestEmbeddedTextFilter.SetUp; +begin + inherited; + FLuaEngine := TLuaEngine.Create; +end; + +procedure TTestEmbeddedTextFilter.TearDown; +begin + FLuaEngine.Free; + inherited; +end; + +procedure TTestEmbeddedTextFilter.TestDoAllTests; +var + luafiles: TStringDynArray; + f : string; + Filter : TLuaEmbeddedTextFilter; +begin + luafiles := TDirectory.GetFiles('embeddedtextfiltertests', '*.elua'); + TArray.Sort(luafiles); + for f in luafiles do + begin + Filter := TLuaEmbeddedTextFilter.Create; + try + Filter.OutputFunction := 'io.write'; + Filter.TemplateCode := TFile.ReadAllText(f); + Filter.Execute; + TFile.WriteAllText(ChangeFileExt(f, '.lua'), Filter.LuaCode); + try + FLuaEngine.LoadScript(Filter.LuaCode); + FLuaEngine.Execute; // only check if is ok the syntax + except + on E: Exception do + begin + Fail('File ' + f + ' - ' + E.Message); + end; + end; + finally + Filter.Free; + end; + end; +end; + +procedure TTestEmbeddedTextFilter.TestHelperExecAndGet01; +var + r: string; +begin + r := TLuaEmbeddedTextFilter.ExecuteWithResult('hello', + ['nome', 'cognome'], + ['Daniele', 'Teti']); + CheckEquals('hello', r); + + r := TLuaEmbeddedTextFilter.ExecuteWithResult('Hello ,, how are you?', + ['nome', 'cognome'], + ['Daniele', 'Teti']); + CheckEquals('Hello Daniele,Teti, how are you?', r); + + r := TLuaEmbeddedTextFilter.ExecuteWithResult + ('Hello ,, how are you?', + ['nome', 'cognome'], + ['Daniele', 'Teti']); + CheckEquals('Hello Daniele,Teti, ' + + StringOfChar('*', 100) + + ' how are you?', r) +end; + +procedure TTestEmbeddedTextFilter.TestHelperExecAndGetMultiThread; +var + p : TProc; + t1 : TThread; + I : Integer; + ThreadList: TList; + ooo : string; +begin + p := + procedure + var + r: string; + begin + r := TLuaEmbeddedTextFilter.ExecuteWithResult + ('Hello ,, how are you?', + ['nome', 'cognome'], + ['Daniele', 'Teti']); + TThread.Synchronize(nil, + procedure + begin + ooo := ooo + + BoolToStr('Hello Daniele,Teti, ' + + StringOfChar('*', 100) + + ' how are you?' = r)[1]; + end); + end; + ooo := ''; + ThreadList := TList.Create; + try + for I := 1 to 50 do + begin + t1 := TThread.CreateAnonymousThread(p); + t1.FreeOnTerminate := false; + t1.Start; + ThreadList.Add(t1); + end; + + while ThreadList.Count > 0 do + begin + ThreadList[0].WaitFor; + ThreadList[0].Free; + ThreadList.Delete(0); + end; + CheckEquals(StringOfChar('T', 50), ooo); + finally + ThreadList.Free; + end; +end; + +initialization + +// Register any test cases with the test runner +RegisterTest(TTestEmbeddedTextFilter.Suite); + +end. diff --git a/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas new file mode 100644 index 00000000..b8ce6f1c --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas @@ -0,0 +1,579 @@ +unit TestLuaWrapper; +{ + + Delphi DUnit Test Case + ---------------------- + This unit contains a skeleton test case class generated by the Test Case Wizard. + Modify the generated code to correctly setup and call the methods from the unit + being tested. + +} +{ .$RTTI EXPLICIT METHODS([vcPublished, vcPublic]) } + +interface + +uses + TestFramework, + System.Classes, + LuaBind.Intf, + LuaBind, + System.Rtti, + System.SysUtils; + +type + // Test methods for class TLuaEngine + + TestTLuaEngine = class(TTestCase) + strict private + FLuaEngine: TLuaEngine; + + private + + public + procedure SetUp; override; + procedure TearDown; override; + + published + procedure TestLoadScript; + procedure TestLoadScript1; + procedure TestLoadFromFile; + procedure TestDeclareGlobalNil; + procedure TestDeclareGlobalNumber; + procedure TestDeclareGlobalInteger; + procedure TestDeclareGlobalString; + procedure TestDeclareGlobalBoolean; + procedure TestDeclareGlobalLightUserData; + procedure TestDeclareGlobalUserData; + /// ///// + procedure TestDeclareGlobalFunction; + procedure TestGetGlobal; + + /// ///test core extensions + procedure TestExposeDataSet; + procedure TestExposeDelphiObject; + procedure TestExposeDelphiObjectNoDeps; + procedure TestExposeVCLDelphiObject; + procedure TestExposeVCLDelphiObjectSetProperty; + procedure TestCreateDelphiObject; + procedure TestCreateDelphiObjectWithWringConstructor; + + /// ///// test helper pusher + procedure TestPushTableWithIntegerKeys; + procedure TestPushTableWithStringKeys; + procedure TestPushTableWithTValueValues; + procedure TestPushTableFromCompoundObject; + + /// //// + procedure TestExecuteFunction; + + procedure TestMyDirtyTests; + + end; + +implementation + +uses + System.IOUtils, + LuaBind.CustomType.DataSet, + Datasnap.DBClient, + LuaBind.CustomType.PODO, + LuaBind.CustomType.UserType, + System.Generics.Collections, + TestObjects; + +procedure TestTLuaEngine.SetUp; +begin + FLuaEngine := TLuaEngine.Create; +end; + +procedure TestTLuaEngine.TearDown; +begin + FLuaEngine.Free; + FLuaEngine := nil; +end; + +procedure TestTLuaEngine.TestLoadScript; +var + AScript: AnsiString; +begin + FLuaEngine.LoadScript(AScript); + FLuaEngine.Execute; + + FLuaEngine.LoadScript('local x = 1+2+3;'); + FLuaEngine.Execute; + + ExpectedException := ELuaRuntimeException; + FLuaEngine.LoadScript('local x = pippo.makeBooom();'); + FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestLoadScript1; +var + AStream: TStream; +begin + AStream := TFile.OpenRead('test_01.lua'); + FLuaEngine.LoadScript(AStream, true); + FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestMyDirtyTests; +begin + FLuaEngine.LoadExternalLibraries(TLuaMyTest.Create); + FLuaEngine.LoadFromFile('test_mydirtytest.lua'); + FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestPushTableFromCompoundObject; +var + father, Child: TPerson; +begin + father := TPerson.Create; + try + father.Child := TPerson.Create; + try + father.FirstName := 'Daniele'; + father.LastName := 'Teti'; + father.Age := 32; + father.Child.FirstName := 'Daniele Son'; + father.Child.LastName := 'Teti'; + father.Child.Age := 2; + father.Child.Child := nil; + FLuaEngine.DeclareTable('person', father); + FLuaEngine.LoadScript + ('s = person.FirstName .. person.LastName .. tostring(person.Age) .. person.Child.FirstName .. person.Child.LastName .. person.Child.Age'); + FLuaEngine.Execute; + CheckEquals('DanieleTeti32Daniele SonTeti2', FLuaEngine.GetGlobal('s').GetAsString); + finally + father.Child.Free; + end; + finally + father.Free; + end; +end; + +procedure TestTLuaEngine.TestPushTableWithIntegerKeys; +begin + FLuaEngine.DeclareTable('mytable', [1, 2, 3, 4], ['daniele', 'teti', 'peter', 'parker']); + FLuaEngine.LoadScript('s = mytable[1]..mytable[2]..mytable[3]..mytable[4]'); + FLuaEngine.Execute; + CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s').GetAsString) +end; + +procedure TestTLuaEngine.TestPushTableWithStringKeys; +begin + FLuaEngine.DeclareTable('mytable', ['a', 'b', 'c', 'd'], ['daniele', 'teti', 'peter', 'parker']); + FLuaEngine.LoadScript( + 's1 = mytable["a"] .. mytable["b"] .. mytable["c"] .. mytable["d"];' + + 's2 = mytable.a .. mytable.b .. mytable.c .. mytable.d'); + FLuaEngine.Execute; + CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s1').GetAsString); + CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s2').GetAsString) +end; + +procedure TestTLuaEngine.TestPushTableWithTValueValues; +var + dict: TDictionary; +begin + dict := TDictionary.Create; + try + dict.AddOrSetValue('hello', 'world'); + dict.AddOrSetValue(1234, 'onetwothree'); + dict.AddOrSetValue('yes', true); + dict.AddOrSetValue('no', false); + FLuaEngine.DeclareTable('mytable', dict); + FLuaEngine.LoadScript + ('s = mytable.hello .. mytable[1234] .. tostring(mytable.yes) .. tostring(mytable["no"])'); + FLuaEngine.Execute; + CheckEquals('worldonetwothreetruefalse', FLuaEngine.GetGlobal('s').GetAsString) + finally + dict.Free; + end; +end; + +procedure TestTLuaEngine.TestLoadFromFile; +begin + FLuaEngine.LoadFromFile('test_01.lua'); + FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestDeclareGlobalNil; +begin + FLuaEngine.DeclareGlobalNil('_nil'); + FLuaEngine.LoadScript(''); + FLuaEngine.Execute; + CheckTrue(FLuaEngine.GetGlobal('_nil').IsNil); +end; + +procedure TestTLuaEngine.TestDeclareGlobalNumber; +var + Value : ILuaValue; + _tot, _number1, _number2, _number3, _number4: Double; +begin + _number1 := 1; + _number2 := 1.1234; + _number3 := 1234.5678; + _number4 := 12345678; + FLuaEngine.DeclareGlobalNumber('_number1', _number1); + FLuaEngine.DeclareGlobalNumber('_number2', _number2); + FLuaEngine.DeclareGlobalNumber('_number3', _number3); + FLuaEngine.DeclareGlobalNumber('_number4', _number4); + + FLuaEngine.LoadScript('_tot = _number1 + _number2 + _number3 + _number4;'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('_tot'); + + CheckTrue(Value.IsNumber); + CheckFalse(Value.IsInteger); + CheckFalse(Value.IsString); + CheckFalse(Value.IsNil); + CheckFalse(Value.IsBoolean); + CheckFalse(Value.IsLightUserData); + + _tot := _number1 + _number2 + _number3 + _number4; + CheckTrue(abs(_tot - Value.GetAsNumber) < 0.0001); + + ExpectedException := ELuaException; + Value.GetAsString; +end; + +procedure TestTLuaEngine.TestDeclareGlobalInteger; +var + Value : ILuaValue; + _tot, _number1, _number2, _number3, _number4: Integer; +begin + _number1 := 1; + _number2 := 1234; + _number3 := 12345678; + _number4 := 12345678; + FLuaEngine.DeclareGlobalInteger('_number1', _number1); + FLuaEngine.DeclareGlobalInteger('_number2', _number2); + FLuaEngine.DeclareGlobalInteger('_number3', _number3); + FLuaEngine.DeclareGlobalInteger('_number4', _number4); + + FLuaEngine.LoadScript('_tot = _number1 + _number2 + _number3 + _number4;'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('_tot'); + + CheckTrue(Value.IsNumber); + /// a sum of integers returns a NUMBER result type.. :-( + CheckFalse(Value.IsInteger); + CheckFalse(Value.IsString); + CheckFalse(Value.IsNil); + CheckFalse(Value.IsBoolean); + CheckFalse(Value.IsLightUserData); + + _tot := _number1 + _number2 + _number3 + _number4; + CheckTrue(abs(_tot - Value.GetAsNumber) < 0.0001); + + ExpectedException := ELuaException; + Value.GetAsString; +end; + +procedure TestTLuaEngine.TestDeclareGlobalString; +var + Value : ILuaValue; + _tot, _string1, _string2, _string3, _string4: AnsiString; +begin + _string1 := ''; + _string2 := 'hello'; + _string3 := 'Lua'; + _string4 := 'world àèéùòìçò§£$%'; + FLuaEngine.DeclareGlobalString('_string1', _string1); + FLuaEngine.DeclareGlobalString('_string2', _string2); + FLuaEngine.DeclareGlobalString('_string3', _string3); + FLuaEngine.DeclareGlobalString('_string4', _string4); + + FLuaEngine.LoadScript('_tot = _string1 .. _string2 .. _string3 .. _string4;'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('_tot'); + + CheckFalse(Value.IsNumber); + CheckFalse(Value.IsInteger); + CheckTrue(Value.IsString); + CheckFalse(Value.IsNil); + CheckFalse(Value.IsBoolean); + CheckFalse(Value.IsLightUserData); + + _tot := _string1 + _string2 + _string3 + _string4; + CheckEquals('helloLuaworld àèéùòìçò§£$%', _tot); + + ExpectedException := ELuaException; + Value.GetAsInteger; +end; + +procedure TestTLuaEngine.TestDeclareGlobalUserData; +begin + // FLuaEngine.DeclareGlobalUserData('pippo', nil); + // FLuaEngine.LoadScript(''); + // FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestExecuteFunction; +var + r: AnsiString; +begin + FLuaEngine.LoadScript('function myfunc(a,b,c) return a..b..c end'); + FLuaEngine.Execute; + r := FLuaEngine.ExecuteFunction('myfunc', ['hello', 'Lua', 'world']).AsString; + CheckEquals('helloLuaworld', r); + FLuaEngine.Reset; + FLuaEngine.LoadFromFile('test_08.lua'); + FLuaEngine.Execute; + r := FLuaEngine.ExecuteFunction('myfunc', ['hello', 'Lua', 'world']).AsString; + CheckEquals('helloLuaworld', r); +end; + +procedure TestTLuaEngine.TestExposeDataSet; +var + ds: TClientDataSet; + _1: string; + _2: string; +begin + ds := TClientDataSet.Create(nil); + try + ds.LoadFromFile('samplecds.xml'); + ds.Open; + FLuaEngine.LoadExternalLibraries(TLuaDataSetExposerLibraries.Create); + ExposeDataSet(FLuaEngine, ds, 'people'); + FLuaEngine.LoadFromFile('test_02.lua'); + FLuaEngine.Execute; + finally + ds.Free; + end; + _1 := TFile.ReadAllText('test_02_expected.txt'); + _2 := TFile.ReadAllText('test_02.txt'); + CheckEquals(_1, _2); +end; + +procedure TestTLuaEngine.TestExposeDelphiObject; +var + person: TPerson; +begin + person := TPerson.Create; + try + FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create); + ExposeDelphiObject(FLuaEngine, person, 'person'); + FLuaEngine.LoadFromFile('test_03.lua'); + FLuaEngine.Execute; + CheckEquals('Teti', FLuaEngine.GetGlobal('last_name').GetAsString); + CheckEquals('Daniele', FLuaEngine.GetGlobal('first_name').GetAsString); + CheckEquals('Mr. Daniele Teti', FLuaEngine.GetGlobal('full_name').GetAsString); + CheckEquals(32, FLuaEngine.GetGlobal('age').GetAsInteger); + CheckEquals('Teti', person.LastName); + CheckEquals('Daniele', person.FirstName); + CheckEquals(32, person.Age); + finally + person.Free; + end; +end; + +procedure TestTLuaEngine.TestExposeDelphiObjectNoDeps; +var + person: TPerson; +begin + person := TPerson.Create; + try + person.FirstName := 'Daniele'; + person.LastName := 'Teti'; + person.Age := 33; + FLuaEngine.DeclareGlobalDelphiObjectAsTable(person, 'person'); + // FLuaEngine.ExecuteScript('r = person.FirstName .. person.LastName .. tostring(person.Age)'); + // CheckEquals('DanieleTeti33', FLuaEngine.GetGlobal('r').GetAsString); + + FLuaEngine.LoadScript('x = person:hello("parametro1", "parametro2")'); + FLuaEngine.Execute; + // FLuaEngine.ExecuteScript('person:BecomeOlder(1)'); + CheckEquals('DanieleTeti34', FLuaEngine.GetGlobal('x').GetAsString); + finally + person.Free; + end; +end; + +procedure TestTLuaEngine.TestExposeVCLDelphiObject; +var + sl: TStringList; +begin + sl := TStringList.Create; + try + sl.Add('first'); + FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create); + ExposeDelphiObject(FLuaEngine, sl, 'stringlist'); + FLuaEngine.LoadFromFile('test_04.lua'); + FLuaEngine.Execute; + CheckEquals(4, sl.Count); + finally + sl.Free; + end; +end; + +procedure TestTLuaEngine.TestExposeVCLDelphiObjectSetProperty; +var + sl: TStringList; +begin + sl := TStringList.Create; + try + sl.Add('first'); + sl.Add('two'); + sl.Add('three'); + FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create); + ExposeDelphiObject(FLuaEngine, sl, 'stringlist'); + FLuaEngine.LoadFromFile('test_05.lua'); + FLuaEngine.Execute; + CheckEquals(1, sl.Count); + CheckEquals('Daniele Teti', sl[0]); + finally + sl.Free; + end; +end; + +procedure TestTLuaEngine.TestCreateDelphiObject; +begin + FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create); + FLuaEngine.LoadFromFile('test_06.lua'); + FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestCreateDelphiObjectWithWringConstructor; +begin + FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create); + FLuaEngine.LoadFromFile('test_07.lua'); + ExpectedException := ELuaRuntimeException; + FLuaEngine.Execute; +end; + +procedure TestTLuaEngine.TestDeclareGlobalBoolean; +var + Value : ILuaValue; + _tot, _boolean1, _boolean2, _boolean3, _boolean4: boolean; +begin + _boolean1 := true; + _boolean2 := false; + _boolean3 := true; + _boolean4 := false; + FLuaEngine.DeclareGlobalBoolean('_boolean1', _boolean1); + FLuaEngine.DeclareGlobalBoolean('_boolean2', _boolean2); + FLuaEngine.DeclareGlobalBoolean('_boolean3', _boolean3); + FLuaEngine.DeclareGlobalBoolean('_boolean4', _boolean4); + + FLuaEngine.LoadScript('_tot = _boolean1 or _boolean2 and _boolean3 or _boolean4;'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('_tot'); + + CheckFalse(Value.IsNumber); + CheckFalse(Value.IsInteger); + CheckFalse(Value.IsString); + CheckFalse(Value.IsNil); + CheckTrue(Value.IsBoolean); + CheckFalse(Value.IsLightUserData); + + _tot := _boolean1 or _boolean2 and _boolean3 or _boolean4; + CheckEquals(_tot, Value.GetAsBoolean); + + ExpectedException := ELuaException; + Value.GetAsString; +end; + +procedure TestTLuaEngine.TestDeclareGlobalFunction; + function SayHello(L: Plua_State): Integer; cdecl; + var + s: AnsiString; + begin + s := lua_tostring(L, - 1); + s := 'before ' + s + ' after'; + lua_pop(L, 1); + lua_pushstring(L, PAnsiChar(s)); + Result := 1; + end; + +var + Value: ILuaValue; +begin + FLuaEngine.DeclareGlobalFunction('sayhello', @SayHello); + FLuaEngine.LoadScript('x = sayhello("hello world")'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('x'); + CheckEquals('before hello world after', Value.GetAsString); +end; + +procedure TestTLuaEngine.TestDeclareGlobalLightUserData; +var + Value: ILuaValue; + _ptr : Pointer; + Obj : TStringList; + Obj2 : TStringList; + + function AddToTStringList(L: Plua_State): Integer; cdecl; + var + sl: TStringList; + s : AnsiString; + begin + s := lua_tostring(L, - 1); + lua_pop(L, 1); + sl := TStringList(lua_topointer(L, - 1)); + lua_pop(L, 1); + sl.Add(s); + Result := 0; + end; + +begin + _ptr := nil; + FLuaEngine.DeclareGlobalLightUserData('_ptr', _ptr); + FLuaEngine.LoadScript('x = _ptr'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('x'); + CheckTrue(Value.IsLightUserData); + CheckTrue(Value.GetAsLightUserData = nil); + + // Now try to pass a tstringlist + Obj := TStringList.Create; + try + Obj.Add('Hello World'); + _ptr := Pointer(Obj); + FLuaEngine.DeclareGlobalLightUserData('_ptr1', _ptr); + + FLuaEngine.DeclareGlobalFunction('additem', @AddToTStringList); + + FLuaEngine.LoadScript('x = _ptr1; additem(x,"added from Lua")'); + FLuaEngine.Execute; + Value := FLuaEngine.GetGlobal('x'); + + CheckFalse(Value.IsNumber); + CheckFalse(Value.IsInteger); + CheckFalse(Value.IsString); + CheckFalse(Value.IsNil); + CheckFalse(Value.IsBoolean); + CheckTrue(Value.IsLightUserData); + + CheckNotNull(Value.GetAsLightUserData); + _ptr := Value.GetAsLightUserData; + + Obj2 := TStringList(_ptr); + CheckEquals(2, Obj2.Count); + CheckEquals('Hello World', Obj2[0]); + CheckEquals('added from Lua', Obj2[1]); + finally + Obj.Free; + end; + + ExpectedException := ELuaException; + Value.GetAsString; +end; + +procedure TestTLuaEngine.TestGetGlobal; +var + ReturnValue: ILuaValue; + AName : AnsiString; +begin + // TODO: Setup method call parameters + ReturnValue := FLuaEngine.GetGlobal(AName); + // TODO: Validate method results +end; + +{ TPerson } + +initialization + +// Register any test cases with the test runner +RegisterTest(TestTLuaEngine.Suite); + +end. diff --git a/samples/serversideviews_lua/lua4delphi/unittests/TestObjects.pas b/samples/serversideviews_lua/lua4delphi/unittests/TestObjects.pas new file mode 100644 index 00000000..40680cd4 --- /dev/null +++ b/samples/serversideviews_lua/lua4delphi/unittests/TestObjects.pas @@ -0,0 +1,63 @@ +unit TestObjects; + +interface + +type + TPerson = class(TObject) + private + FLastName: String; + FFirstName: String; + FAge: Integer; + FChild: TPerson; + procedure SetLastName(const Value: String); + procedure SetFirstName(const Value: String); + procedure SetAge(const Value: Integer); + procedure SetChild(const Value: TPerson); + public + constructor Create; + function GetFullName(ASalutation: String): String; + procedure BecomeOlder(HowManyYear: Integer); + property Child: TPerson read FChild write SetChild; + property LastName: String read FLastName write SetLastName; + property FirstName: String read FFirstName write SetFirstName; + property Age: Integer read FAge write SetAge; + end; + +implementation + +procedure TPerson.BecomeOlder(HowManyYear: Integer); +begin + FAge := FAge + HowManyYear; +end; + +constructor TPerson.Create; +begin + inherited; +end; + +function TPerson.GetFullName(ASalutation: String): String; +begin + Result := ASalutation + ' ' + FFirstName + ' ' + FLastName; +end; + +procedure TPerson.SetAge(const Value: Integer); +begin + FAge := Value; +end; + +procedure TPerson.SetChild(const Value: TPerson); +begin + FChild := Value; +end; + +procedure TPerson.SetFirstName(const Value: String); +begin + FFirstName := Value; +end; + +procedure TPerson.SetLastName(const Value: String); +begin + FLastName := Value; +end; + +end.