├── .gitattributes ├── data ├── logo.png ├── lua.dll ├── lua64.dll ├── example_vcl.png └── example_method.png ├── tutorials ├── CrystalLUA-eng (depected).pdf ├── CrystalLUA-rus (depected).doc └── CrystalLUA-rus (depected).pdf ├── LICENSE ├── .gitignore └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | data/* filter=lfs diff=lfs merge=lfs -text 2 | tutorials/* filter=lfs diff=lfs merge=lfs -text -------------------------------------------------------------------------------- /data/logo.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eb017806f6189cf47aeaa64c3cd0957c1ef5a976cce01172f0a65792e3bff8f2 3 | size 45397 4 | -------------------------------------------------------------------------------- /data/lua.dll: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e74c63db0f1f0ffa61805ed2e82a4628adbb0fe203456956f20381e4dbb2bb48 3 | size 54784 4 | -------------------------------------------------------------------------------- /data/lua64.dll: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0230213877f8f7b150d9260292d44ab33d3edad6553bcd281c99f6af3490a131 3 | size 196403 4 | -------------------------------------------------------------------------------- /data/example_vcl.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:45020bd3ce0fb3e915e244d1afc7fbd60ebf572fed815eda4c518c4ad29f5616 3 | size 2559 4 | -------------------------------------------------------------------------------- /data/example_method.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:73f002c73a6409136f6ae4efc061f1c8e6a0eb03a237b7a5081d865be5e1c114 3 | size 3823 4 | -------------------------------------------------------------------------------- /tutorials/CrystalLUA-eng (depected).pdf: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:edaccffa09bcaabc87707a828836015d3b54d3f4d3cfab595e51f18a893524fd 3 | size 1996540 4 | -------------------------------------------------------------------------------- /tutorials/CrystalLUA-rus (depected).doc: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:660d51bc607e0023abc6e6fd273b25cb2a97ba80a97769ff2ed2b226a5b6c647 3 | size 878592 4 | -------------------------------------------------------------------------------- /tutorials/CrystalLUA-rus (depected).pdf: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7c3f76beabdc9e7f3be3d0cd998ec9cde9f76f5ffb5629ad25b6721afea86ed9 3 | size 899496 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2010 d-mozulyov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Uncomment these types if you want even more clean repository. But be careful. 2 | # It can make harm to an existing project source. Read explanations below. 3 | # 4 | # Resource files are binaries containing manifest, project icon and version info. 5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. 6 | #*.res 7 | # 8 | # Type library file (binary). In old Delphi versions it should be stored. 9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored. 10 | #*.tlb 11 | # 12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7. 13 | # Uncomment this if you are not using diagrams or use newer Delphi version. 14 | #*.ddp 15 | # 16 | # Visual LiveBindings file. Added in Delphi XE2. 17 | # Uncomment this if you are not using LiveBindings Designer. 18 | #*.vlb 19 | # 20 | # Deployment Manager configuration file for your project. Added in Delphi XE2. 21 | # Uncomment this if it is not mobile development and you do not use remote debug feature. 22 | #*.deployproj 23 | # 24 | 25 | # Delphi compiler-generated binaries (safe to delete) 26 | *.exe 27 | *.dll 28 | *.bpl 29 | *.bpi 30 | *.dcp 31 | *.so 32 | *.apk 33 | *.drc 34 | *.map 35 | *.dres 36 | *.rsm 37 | *.tds 38 | *.dcu 39 | *.lib 40 | 41 | # Delphi autogenerated files (duplicated info) 42 | *.cfg 43 | *Resource.rc 44 | 45 | # Delphi local files (user-specific info) 46 | *.local 47 | *.identcache 48 | *.projdata 49 | *.tvsconfig 50 | *.dsk 51 | 52 | # Delphi history and backups 53 | __history/ 54 | *.~* 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CrystalLUA 2 | 3 | 4 | 5 | [Lua](https://www.lua.org/start.html) is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications. CrystalLUA is a high-level library for binding your native Delphi code and scripts in Lua language. The difference between CrystalLUA and other binding libraries is in high code performance and convenient registration based on RTTI. This project was developed many years ago, you can use an [outdated version](https://github.com/d-mozulyov/CrystalLUA/archive/0.1.zip) (Delphi 6-2007) of the library. 6 | 7 | Now the library is actively developing, despite the fact that not all the features declared in the old versions have been implemented, many others are already supported: Unicode, 64 bits, extended RTTI, executable types (functions, events, references). In addition, the [RLua](https://gitlab.com/d-mozulyov/rlua) fork is being developed, which over time will make CrystalLUA cross-platform and independent of dynamic libraries. 8 | 9 | Below are a few examples that will help you quickly master CrystalLUA. Enjoy :). 10 | 11 | 12 | ### Hello, World! 13 | 14 | `TLua` is the main class of the library, which allows you to execute scripts and register types, functions and variables. Now it uses a dynamic library, so before calling the constructor, you must specify the relative or full path `LuaLibraryPath`. There are several ways to execute a script; the simplest is the `RunScript` method, which takes a script text parameter. 15 | 16 | ```pascal 17 | program HelloWorld; 18 | {$APPTYPE CONSOLE} 19 | uses 20 | SysUtils, CrystalLUA; 21 | var 22 | Lua: TLua; 23 | begin 24 | LuaLibraryPath := {$ifdef CPUX86}'lua.dll'{$else}'lua64.dll'{$endif}; 25 | Lua := TLua.Create; 26 | try 27 | Lua.RunScript('print("Hello, World!\n")'); 28 | finally 29 | Lua.Free; 30 | end; 31 | Write('Press Enter to quit'); 32 | Readln; 33 | end. 34 | ``` 35 | 36 | ``` 37 | Hello, World! 38 | Press Enter to quit 39 | ``` 40 | 41 | ### Script functions calling 42 | 43 | You can load a script from a file, memory or resource using the `LoadScript` method. In this example, the script is loaded from a set of strings that are converted to `TBytes`. You can call any script function and get the result. 44 | 45 | ```pascal 46 | program ScriptFunctions; 47 | {$APPTYPE CONSOLE} 48 | uses 49 | SysUtils, CrystalLUA, Classes; 50 | var 51 | Lua: TLua; 52 | a, b, c, r: Integer; 53 | Bytes: TBytes; 54 | begin 55 | LuaLibraryPath := {$ifdef CPUX86}'lua.dll'{$else}'lua64.dll'{$endif}; 56 | Lua := TLua.Create; 57 | try 58 | a := 1; 59 | b := 2; 60 | c := 3; 61 | Bytes := TEncoding.UTF8.GetPreamble + TEncoding.UTF8.GetBytes( 62 | 'function myfunc(a, b, c)'#13 + 63 | ' return (a + b * c)'#13 + 64 | 'end'); 65 | Lua.LoadScript(Bytes); 66 | Write(a, ' + ', b, ' * ', c, ' = '); 67 | r := Lua.Call('myfunc', [a, b, c]).Items[0].AsInteger; 68 | Writeln(r); 69 | finally 70 | Lua.Free; 71 | end; 72 | Write('Press Enter to quit'); 73 | Readln; 74 | end. 75 | ``` 76 | 77 | ``` 78 | 1 + 2 * 3 = 7 79 | Press Enter to quit 80 | ``` 81 | 82 | 83 | ### Involvement of components (VCL, FMX, etc.) 84 | 85 | The library allows you to bind your native code and scripts. The CrystalLUA namespace contains only those elements that you register in it. But by default, all the information that was found in the RTTI gets into the namespace. Therefore, by registering the global variable `Form1: TForm1`, you get access to all its public properties, methods and child components. 86 | 87 | ```pascal 88 | procedure TForm1.FormCreate(Sender: TObject); 89 | begin 90 | LuaLibraryPath := {$ifdef CPUX86}'lua.dll'{$else}'lua64.dll'{$endif}; 91 | FLua := TLua.Create; 92 | FLua.RegVariable('Form1', Form1, TForm1); 93 | end; 94 | procedure TForm1.FormDestroy(Sender: TObject); 95 | begin 96 | FLua.Free; 97 | end; 98 | procedure TForm1.btnRunClick(Sender: TObject); 99 | begin 100 | // FLua.RunScript('Form1.btnRun.Left = Form1.btnRun.Left + 10'); 101 | FLua.RunScript('Form1.Caption = "Component property changed!"'); 102 | end; 103 | ``` 104 | ![](data/example_vcl.png) 105 | 106 | 107 | ### Native functions calling 108 | 109 | Modern Delphi allows you to receive declared [methods RTTI](http://docwiki.embarcadero.com/RADStudio/Rio/en/RTTI_directive_(Delphi)). This example demonstrates how to call a native function from a script. 110 | 111 | ```pascal 112 | public 113 | { Public declarations } 114 | function AskQuestion(const ATitle, AQuestion: string): Boolean; 115 | end; 116 | 117 | function TForm1.AskQuestion(const ATitle, AQuestion: string): Boolean; 118 | begin 119 | Result := Application.MessageBox(PChar(AQuestion), PChar(ATitle), MB_YESNO) = IDYES; 120 | end; 121 | procedure TForm1.btnRunClick(Sender: TObject); 122 | begin 123 | // FLua.RunScript('Form1:Close()'); 124 | FLua.RunScript('Form1.Caption = tostring(Form1:AskQuestion("My title", "Do you like the library?"))'); 125 | end; 126 | ``` 127 | ![](data/example_method.png) 128 | 129 | 130 | ### Executable types 131 | 132 | The library allows you to read, modify and execute types such as functions, events, references. Remember that references have RTTI if `{$M+}` directive declared. The example below shows how to read and execute a variable of your type. 133 | 134 | ```pascal 135 | type 136 | {$M+} 137 | TMyReference = reference to function(const ATitle, AQuestion: string): Boolean; 138 | TForm1 = class(TForm) 139 | btnRun: TButton; 140 | procedure FormCreate(Sender: TObject); 141 | procedure FormDestroy(Sender: TObject); 142 | procedure btnRunClick(Sender: TObject); 143 | private 144 | FLua: TLua; 145 | FMyReference: TMyReference; 146 | function AskQuestion(const ATitle, AQuestion: string): Boolean; 147 | public 148 | property MyReference: TMyReference read FMyReference write FMyReference; 149 | end; 150 | 151 | procedure TForm1.FormCreate(Sender: TObject); 152 | begin 153 | LuaLibraryPath := {$ifdef CPUX86}'lua.dll'{$else}'lua64.dll'{$endif}; 154 | FLua := TLua.Create; 155 | FLua.RegVariable('Form1', Form1, TForm1); 156 | FMyReference := AskQuestion; 157 | end; 158 | procedure TForm1.FormDestroy(Sender: TObject); 159 | begin 160 | FLua.Free; 161 | end; 162 | procedure TForm1.btnRunClick(Sender: TObject); 163 | begin 164 | FLua.RunScript( 165 | 'local Func = Form1.MyReference'#13 + 166 | 'Form1.Caption = tostring(Func("My title", "Do you like the library?"))'); 167 | end; 168 | ``` --------------------------------------------------------------------------------