Skip to content

Commit

Permalink
doc update
Browse files Browse the repository at this point in the history
  • Loading branch information
ikappaki committed Aug 2, 2024
1 parent 891cd9c commit 71550ac
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 45 deletions.
65 changes: 51 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Basilisp Blender Integration

[Basilisp](https://github.com/basilisp-lang/basilisp) is a Python-based Lisp implementation that offers broad compatibility with Clojure.
[Basilisp](https://github.com/basilisp-lang/basilisp) is a Python-based Lisp implementation that offers broad compatibility with Clojure. For more details, refer to the [documentation](https://basilisp.readthedocs.io/en/latest/index.html).

## Overview
`basilisp-blender` is a Python library designed to facilitate the execution of Basilisp code within Blender and manage an nREPL server for interactive programming. This library provides functions to evaluate Basilisp code from Blender's Python console, file or Text Editor and to start an nREPL server, allowing seamless integration and communication with Basilisp.
Expand Down Expand Up @@ -37,8 +37,7 @@ To evaluate Basilisp code from a file:
```python
from basilisp_blender.eval import eval_file

file_path = "path/to/your/file.lpy"
eval_file(file_path)
eval_file("path/to/your/code.lpy")
```

#### From Blender’s Text Editor
Expand All @@ -57,7 +56,6 @@ To start an nREPL server within Blender:
```python
from basilisp_blender.nrepl import server_start

```python
shtudown_fn = server_start(host="127.0.0.1", port=8889)
```

Expand All @@ -73,13 +71,13 @@ shtudown_fn = server_start(nrepl_port_filepath="<project-root-path>/.nrepl-port"

Replace `<project-root-path>` with the path to your project's root directory.

#Example
# Examples

Basilisp code to create a torus pattern using the `bpy` Blender library:
Here is an example of Basilisp code to create a torus pattern using the bpy Blender Python library:

```clojure
(ns torus-pattern
"Creates a torus pattern with random colored materials."
"Creates a torus pattern with randomly colored materials."
(:import bpy
math))

Expand All @@ -105,13 +103,13 @@ Basilisp code to create a torus pattern using the `bpy` Blender library:
mat))

(defn create-torus [radius tube-radius location segments]
(let [_ (.primitive-torus-add mesh **
:major-radius radius
:minor-radius tube-radius
:location location
:major-segments segments
:minor-segments segments)
obj (-> bpy/context .-object)
(.primitive-torus-add mesh **
:major-radius radius
:minor-radius tube-radius
:location location
:major-segments segments
:minor-segments segments)
(let [obj (-> bpy/context .-object)
material (create-random-material)]
(-> obj .-data .-materials (.append material))))

Expand All @@ -137,3 +135,42 @@ Basilisp code to create a torus pattern using the `bpy` Blender library:

![torus pattern example img](examples/torus-pattern.png)

# Development

## Testing

You can run tests using the following command:

```bash
$ poetry run pytest
```
### Integration testing

To run integration tests, set the `$BB_BLENDER_TEST_HOME` environment variable to the root directory of the Blender installation where the development package is installed. See next section on how to facilitate the installation.

```bash
$ export BB_BLENDER_TEST_HOME="~/blender420"
# or on MS-Windows
> $env:BB_BLENDER_TEST_HOME="c:\local\blender420"
```
Then run the integration tests with

```bash
$ poetry run pytest -m integration
```

### Installing Blender and the Development Package

To download and install Blender in the directory specified by `$BB_BLENDER_TEST_HOME`, use:

```bash
$ poetry run python scripts/blender_install.py 4.2.0
```

To install the development version of the package at the same location, use:

```bash
$ poetry build # build the package
$ poetry run python scripts/bb_install.py # install it in Blender
```

16 changes: 8 additions & 8 deletions examples/torus_pattern.lpy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns torus-pattern
"Creates a torus pattern with random colored materials."
"Creates a torus pattern with randomly colored materials."
(:import bpy
math))

Expand All @@ -25,13 +25,13 @@
mat))

(defn create-torus [radius tube-radius location segments]
(let [_ (.primitive-torus-add mesh **
:major-radius radius
:minor-radius tube-radius
:location location
:major-segments segments
:minor-segments segments)
obj (-> bpy/context .-object)
(.primitive-torus-add mesh **
:major-radius radius
:minor-radius tube-radius
:location location
:major-segments segments
:minor-segments segments)
(let [obj (-> bpy/context .-object)
material (create-random-material)]
(-> obj .-data .-materials (.append material))))

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "basilisp-blender"
version = "0.0.0b28"
version = "0.0.0b29"
description = ""
authors = ["ikappaki"]
readme = "README.md"
Expand Down
59 changes: 37 additions & 22 deletions src/basilisp_blender/nrepl_server.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,9 @@
:recv-buffer-size The buffer size to using for incoming nREPL
messages.

:work* An optional atom containing a map. If provided, it stores
client entries where each key represents information about the
connected client and each value is a queue of requests to be
processed later, rather than immediately."
:work* An optional atom containing a map. If provided, client
requests are queued in the map under a client information key,
rather than being executed imediately."
(let [{:keys [recv-buffer-size work*]
:or {recv-buffer-size 1024}} opts
socket (.-request tcp-req-handler)
Expand Down Expand Up @@ -426,9 +425,13 @@
the optional `notify-fn` with the client information and the
request to be executed.

`work` is an atom that holds a map. In this map, each key
represents a client information object, and each value is a
`queue.Queue` containing client request functions to be executed."
`work*` is an atom containing a map where each key represents a
client information object, and each value is a `queue.Queue` of
request functions to be executed.

The optional `notify-fn` argument is a 2-arity function that will be
called with the client information and the request that is about to
be executed."
([work*]
(clients-work-do! work* nil))
([work* notify-fn]
Expand Down Expand Up @@ -475,14 +478,14 @@
(socketserver/ThreadingTCPServer (python/tuple [host port]) handler)))

(defn server-shutdown!
"Shutdown the server contained in the `server*` atom."
"Shutdown the `server`, and optionally close it if `close?` is true."
([server]
(server-shutdown! server false))
([server wait?]
([server close?]
(debug ":server-shutting-down")
(.shutdown server)
(debug ":server-close")
(when wait?
(when close?
(.server-close server))
(debug ":server-close-done")))

Expand All @@ -500,11 +503,26 @@

``opts`` is a map of options with the following optional keys


:async? If true, runs the server in asynchronous where requests are
queued rather than executed immediately. This mode requires that
the :server* key is present in the ``opts``
map. The :server*'s :work-fn key will be set to a function that
processes all pending work (see :atoms* below).

:nrepl-port-file An option filepath to write the port number
to. This is typically set to .nrepl-port for the editors to pick up.

:server* An atom to hold the server reference as returned from
:lpy:fn:`server-make`, useful for testing.
:server* A map atom. The map may contains an optional :start-event
key with a `threading.Event` value. This event is set when the
server is about to enter its main loop or if it fails to start. The
map will be populated with the following keys

:server Set to the server reference.

:work-fn When in `async?` mode, set to a function that executes all pending work.

:shutdown-fn set to a function that can be called to shut down the server.

also see :lpy:fn:`server-make` for additionally supported
``opts`` keys."
Expand All @@ -520,14 +538,11 @@
(error "Error: async server requires the server* option.")

(try
(when server* (reset! server* {:server server
:start-event start-event
:work-fn (fn
([]
(clients-work-do! work*))
([notify-fn]
(clients-work-do! work* notify-fn)))
:shutdown-fn (partial server-shutdown! server)}))
(when server* (reset! server* (cond-> {:server server
:start-event start-event
:shutdown-fn (partial server-shutdown! server)}
async?
(assoc :work-fn (partial clients-work-do! work*)))))
(let [[host port] (py->lisp (.-server-address server))]
(binding [*out* sys/stdout]
(println (format nrepl-server-signature port host host port)))
Expand All @@ -549,8 +564,8 @@
server* (atom {:start-event start-event})
opts (assoc opts :async? true :server* server*)
start-fn #(start-server! opts)
thread (threading/Thread ** :target start-fn :daemon true)
_ (.start thread)]
thread (threading/Thread ** :target start-fn :daemon true)]
(.start thread)
(if (.wait start-event 10)
(-> (select-keys @server* [:server :work-fn :shutdown-fn])
(assoc :server-thread thread))
Expand Down

0 comments on commit 71550ac

Please sign in to comment.