Skip to content

Commit

Permalink
Add more doc on LuaValue
Browse files Browse the repository at this point in the history
  • Loading branch information
gudzpoz committed May 27, 2024
1 parent 89601b8 commit 644778c
Show file tree
Hide file tree
Showing 9 changed files with 1,514 additions and 950 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ Optionally, you may include `party.iroiro.luajava:jsr223` to provide JSR 223 fun
### Examples

Here is a simple example on how to correctly initialize new Lua instance.
This example will push `message` variable to Lua with value `Hello World from Lua`, then prints it using the Java `println`.
This example will push `message` variable to Lua with value `Hello World from Lua`,
and then print it using the Java `println`.

```java
public static void main(String[] args) {
try (Lua L = new Lua51()) {
L.push("Hello World from LuaJava");
L.setGlobal("message");
L.set("message", "Hello World from LuaJava");
L.run("java.import('java.lang.System').out:println(message)");
}
}
Expand Down
21 changes: 16 additions & 5 deletions docs/.vuepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { defineUserConfig, defaultTheme } from 'vuepress'
const { registerComponentsPlugin } = require('@vuepress/plugin-register-components')
const { path } = require('@vuepress/utils')
import { defineUserConfig } from 'vuepress'
import { viteBundler } from '@vuepress/bundler-vite'
import { defaultTheme } from '@vuepress/theme-default'
import { registerComponentsPlugin } from '@vuepress/plugin-register-components'
import { path } from '@vuepress/utils'

import markdownItFootnote from 'markdown-it-footnote'

export default defineUserConfig({
lang: 'en-US',
title: 'LuaJava',
description: 'Lua for Java',
base: '/luajava/',
head: [['link', { rel: 'icon', href: '/luajava/favicon.png' }]],
bundler: viteBundler(),
theme: defaultTheme({
logo: '/lua-java.svg',
repo: 'https://github.com/gudzpoz/luajava',
Expand Down Expand Up @@ -44,10 +49,16 @@ export default defineUserConfig({
'/threadsafety.md',
]
},
{
text: 'Java API',
children: [
'/java.md',
'/c-api.md',
],
},
{
text: 'Examples',
children: [
'/examples/java.md',
'/examples/compat.md',
'/examples/hello-world.md',
'/examples/hello-world-mod.md',
Expand All @@ -71,7 +82,7 @@ export default defineUserConfig({
},
},
extendsMarkdown (md) {
md.use(require('markdown-it-footnote'))
md.use(markdownItFootnote)
},
plugins: [
registerComponentsPlugin({
Expand Down
179 changes: 179 additions & 0 deletions docs/c-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Lua Stack-based C API

The [`party.iroiro.luajava.Lua`](../javadoc/party/iroiro/luajava/Lua.html) interface
is a wrapper around the `lua_State` pointer.
Besides [`LuaValue`-relevant methods](./java.md),
it also provides the common parts from the C APIs of Lua 5.1 ~ 5.4 and LuaJIT.
(You are recommended to use [the `LuaValue` API](./java.md) though.)
You may refer to the Javadoc for more information.

## `Lua` <Badge>interface</Badge>

The Java API is mostly a wrapper around
[The Application Program Interface of Lua](https://www.lua.org/manual/5.1/manual.html).
Some common patterns are listed below to help you get started.

### Setting a global value

Lua API bases on a Lua stack. You need to push the value onto the stack before assigning it
to a global value with [`setGlobal`](../javadoc/party/iroiro/luajava/Lua.html#setGlobal(java.lang.String)).

<!-- @code:globalSetTest -->
@[code{112-120} java{6-7}](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

### Getting a global value

Similarly, [`getGlobal`](../javadoc/party/iroiro/luajava/Lua.html#getGlobal(java.lang.String))
pushes a value onto the stack, instead of returning it.

<!-- @code:globalGetTest -->
@[code{125-132} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

### Querying a table

We need to make use of
[`getField`](../javadoc/party/iroiro/luajava/Lua.html#getField(int,java.lang.String)),
[`getTable`](../javadoc/party/iroiro/luajava/Lua.html#getTable(int)),
[`rawGet`](../javadoc/party/iroiro/luajava/Lua.html#rawGetI(int,int))
or [`rawGetI`](../javadoc/party/iroiro/luajava/Lua.html#rawGetI(int,int)).

:::: code-group
::: code-group-item getField

<!-- @code:getFieldTest -->
@[code{137-141} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item rawGetI

<!-- @code:rawGetITest -->
@[code{146-150} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item getTable

<!-- @code:getTableTest -->
@[code{155-160} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item rawGet

<!-- @code:rawGetTest -->
@[code{165-170} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::::

### Updating a table

Similarly, we have
[`setField`](../javadoc/party/iroiro/luajava/Lua.html#setField(int,java.lang.String))
[`setTable`](../javadoc/party/iroiro/luajava/Lua.html#setTable(int))
[`rawSet`](../javadoc/party/iroiro/luajava/Lua.html#rawSet(int))
and [`rawSetI`](../javadoc/party/iroiro/luajava/Lua.html#rawSetI(int,int)).

:::: code-group
::: code-group-item setField

<!-- @code:setFieldTest -->
@[code{175-179} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item rawSetI

<!-- @code:rawSetITest -->
@[code{184-188} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item setTable

<!-- @code:setTableTest -->
@[code{193-198} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item rawSet

<!-- @code:rawSetTest -->
@[code{203-208} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::::

### Creating references

A reference is a unique integer key: `table[reference] = referredValue`. Lua provides a convenient way to store values into a table, returning the generated reference key.

See
[`ref()`](../javadoc/party/iroiro/luajava/Lua.html#ref())
[`ref(int)`](../javadoc/party/iroiro/luajava/Lua.html#ref(int))
[`refGet(int)`](../javadoc/party/iroiro/luajava/Lua.html#refGet(int))
[`unref(int)`](../javadoc/party/iroiro/luajava/Lua.html#unref(int))
and [`unRef(int, int)`](../javadoc/party/iroiro/luajava/Lua.html#unRef(int,int)) for more info.

### Pre-compiled chunks

According to the Lua reference manual:

> Chunks can also be pre-compiled into binary form;
> see program luac for details.
> Programs in source and compiled forms are interchangeable;
> Lua automatically detects the file type and acts accordingly.
Replacing Lua source files with pre-compiled chunks speeds up loading.
However, according to `luac` manual:

> Precompiled chunks are *not* portable across different architectures.
> Moreover, the internal format of precompiled chunks is likely to change
> when a new version of Lua is released. Make sure you save the source
> files of all Lua programs that you precompile.
Binary chunks compiled on one platform may not run on another.
Since we are using Java / JVM-based languages, this is absolutely not desirable.
To work around this, you may either:
1. Provide precompiled chunks for all your target platforms;
2. Or compile them at runtime for once and just reuse the compiled binaries.

Here is a tiny example for the second approach:

:::: code-group
::: code-group-item Use lua_dump

<!-- @code:luaDumpTest -->
@[code{221-228} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::: code-group-item Use `string.dump`

<!-- @code:stringDumpTest -->
@[code{233-240} java](../example/src/test/java/party/iroiro/luajava/docs/JavaApiExampleTest.java)

:::
::::

Dumping functions involves some more Lua knowledge such as up-values and environments.
What these terms mean might differ between versions and is not a topic of this document.

## `LuaNatives` <Badge>interface</Badge>

The [`LuaNatives`](../javadoc/party/iroiro/luajava/LuaNatives.html) interface
exposes common JNI bindings of the C API of Lua 5.1 ~ Lua 5.4.
Use with caution.

- Get an instance of `LuaValue` with [`LuaValue::getLuaNatives()`](../javadoc/party/iroiro/luajava/Lua.html#getLuaNatives()).
- Get the pointer to a `Lua` state with [`Lua::getPointer()`](../javadoc/party/iroiro/luajava/Lua.html#getPointer()).

If you want to use C API functions specific to a Lua version,
simply cast them to the corresponding `LuaNatives` implementation:

- [`Lua51Natives`](../javadoc/party/iroiro/luajava/lua51/Lua51Natives.html)
- [`Lua52Natives`](../javadoc/party/iroiro/luajava/lua52/Lua52Natives.html)
- [`Lua53Natives`](../javadoc/party/iroiro/luajava/lua53/Lua53Natives.html)
- [`Lua54Natives`](../javadoc/party/iroiro/luajava/lua54/Lua54Natives.html)
- [`LuaJitNatives`](../javadoc/party/iroiro/luajava/luajit/LuaJitNatives.html)
- [`LuaJNatives`](../javadoc/party/iroiro/luajava/luaj/LuaJNatives.html)

::: tip
`LuaJNatives`, which uses LuaJ, a Lua implementation in Java,
is actually implemented in Java to provide a consistent API.
It should not differ too much from other implementations though.
:::
Loading

0 comments on commit 644778c

Please sign in to comment.