ユーザ用ツール

サイト用ツール


youtube:python-mixing-009

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
youtube:python-mixing-009 [2024/02/28 18:26] – 削除 - 外部編集 (不明な日付) 127.0.0.1youtube:python-mixing-009 [2024/02/28 18:26] (現在) – ↷ toybox:python-mixing-009 から youtube:python-mixing-009 へページを移動しました。 freemikan
行 1: 行 1:
 +====== PyO3でLÖVEもどきを作る (2) ======
 +
 +作成日: 2023-08-14 (月)
 +
 +[[https://youtu.be/x0HpQJHWK1w|第9回 PyO3でLÖVEもどきを作る (2)]]
 +
 +===== プロジェクト pyove =====
 +
 +==== Cargo.toml ====
 +
 +<file toml>
 +[package]
 +name = "pyove"
 +version = "0.1.0"
 +edition = "2021"
 +
 +[dependencies.pyo3]
 +version = "0.19.2"
 +features = ["auto-initialize", "macros"]
 +</file>
 +
 +==== src/main.rs ====
 +
 +<file rust>
 +use pyo3::prelude::*;
 +use std::{env, path::Path, process::exit};
 +
 +pub mod graphics;
 +
 +#[pyfunction]
 +fn load() {
 +    println!("default load");
 +}
 +
 +#[pyfunction]
 +fn draw() {
 +    println!("default draw");
 +}
 +
 +#[pyfunction]
 +fn update(dt: f32) {
 +    println!("default update {}", dt);
 +}
 +
 +#[pymodule]
 +fn pyove(py: Python<'_>, m: &PyModule) -> PyResult<()> {
 +    m.add_function(wrap_pyfunction!(load, m)?)?;
 +    m.add_function(wrap_pyfunction!(draw, m)?)?;
 +    m.add_function(wrap_pyfunction!(update, m)?)?;
 +    graphics::register_graphics_module(py, m)?;
 +    Ok(())
 +}
 +
 +fn main() -> PyResult<()> {
 +    //
 +    // コマンドライン引数のパース
 +    //
 +    let args: Vec<String> = env::args().collect();
 +    if args.len() != 2 {
 +        // コマンドライン引数がただ1つだけ与えられていなければ終了する
 +        eprintln!("Usage: {} GAMEDIR", args[0]);
 +        exit(1);
 +    }
 +
 +    let gamedir = Path::new(&args[1]);
 +    let main_file = gamedir.join("main.py");
 +    if !main_file.exists() {
 +        // main.pyが存在しなければ終了する
 +        eprintln!("Error: {} not exists.", main_file.to_str().unwrap());
 +        exit(2);
 +    }
 +
 +    // main.pyの内容を読み込む
 +    let main_code = std::fs::read_to_string(main_file)?;
 +
 +    //
 +    // activate Python interpreter
 +    //
 +
 +    // pyoveをモジュールとして登録
 +    pyo3::append_to_inittab!(pyove);
 +
 +    Python::with_gil(|py| {
 +        // ゲームディレクトリをインポートパスに追加する
 +        let sys_path_code = format!(
 +            "import sys; sys.path.append('{}')",
 +            gamedir.to_str().unwrap()
 +        );
 +        py.run(&sys_path_code, None, None)?;
 +
 +        // pyoveモジュールにアクセスしたいので、ここでインポートする
 +        let pyove = PyModule::import(py, "pyove")?;
 +
 +        // main.pyを実行
 +        py.run(&main_code, None, None)?;
 +
 +        // main.pyでこの3つの関数は置き換え可能
 +        let load_fn = pyove.getattr("load")?;
 +        let update_fn = pyove.getattr("update")?;
 +        let draw_fn = pyove.getattr("draw")?;
 +
 +        // 試しにloadとupdateとdrawを実行してみる
 +        load_fn.call0()?;
 +        update_fn.call1((123,))?;
 +        draw_fn.call0()?;
 +
 +        Ok(())
 +    })
 +}
 +</file>
 +
 +==== src/graphics.rs ====
 +
 +<file rust>
 +//
 +// このプロジェクトではset_colorとrectangle関数のみを提供する
 +//
 +use pyo3::prelude::*;
 +
 +#[pyfunction]
 +#[pyo3(name = "setColor")]
 +fn set_color(r: f32, g: f32, b: f32) {
 +    // 仮の処理
 +    println!("setColor {} {} {}", r, g, b);
 +}
 +
 +#[pyfunction]
 +fn rectangle(mode: &str, x: i32, y: i32, w: i32, h: i32) {
 +    // 仮の処理
 +    println!("rectangle {} {} {} {} {}", mode, x, y, w, h)
 +}
 +
 +pub fn register_graphics_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> {
 +    // see: https://pyo3.rs/v0.19.2/module#python-submodules
 +    // サブモジュールとしてgraphicsを登録する
 +    // graphicsに、setColorとrectangleを登録する
 +    let m = PyModule::new(py, "graphics")?;
 +    m.add_function(wrap_pyfunction!(set_color, m)?)?;
 +    m.add_function(wrap_pyfunction!(rectangle, m)?)?;
 +    parent_module.add_submodule(m)?;
 +    Ok(())
 +}
 +</file>
 +
 +==== example/main.py ====
 +
 +<file python>
 +import pyove
 +#import foo # test import availability
 +
 +# Python requires global scoped variable definitions
 +x, y, w, h = 0, 0, 0, 0
 +
 +def load():
 +    global x, y, w, h
 +    x, y, w, h = 20, 20, 60, 20
 +
 +def update(dt):
 +    global w, h
 +    w += 1
 +    h += 1
 +
 +def draw():
 +    pyove.graphics.setColor(0, 0.4, 0.4)
 +    pyove.graphics.rectangle("fill", x, y, w, h)
 +
 +# overwrite default module functions
 +pyove.load = load
 +pyove.draw = draw
 +pyove.update = update
 +</file>
 +
 +=== 参考 ===
 +
 +オリジナルの動作は、こちらを参考にしてください。
 +
 +  * https://love2d.org/wiki/love
  

特に明示されていない限り、本Wikiの内容は次のライセンスに従います: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki