ソースを参照

add `conio` module

blueloveTH 1 年間 前
コミット
362283627e

+ 0 - 9
CMakeLists.txt

@@ -44,11 +44,6 @@ if(PK_ENABLE_OS)
     add_definitions(-DPK_ENABLE_OS=1)
     add_definitions(-DPK_ENABLE_OS=1)
 endif()
 endif()
 
 
-option(PK_MODULE_WIN32 "" OFF)
-if(PK_MODULE_WIN32)
-    add_definitions(-DPK_MODULE_WIN32=1)
-endif()
-
 # PK_IS_MAIN determines whether the project is being used from root
 # PK_IS_MAIN determines whether the project is being used from root
 # or if it is added as a dependency (through add_subdirectory for example).
 # or if it is added as a dependency (through add_subdirectory for example).
 if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
 if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -87,7 +82,3 @@ if(UNIX)
         target_link_libraries(${PROJECT_NAME} dl)
         target_link_libraries(${PROJECT_NAME} dl)
     endif()
     endif()
 endif()
 endif()
-
-if(PK_MODULE_WIN32)
-    target_link_libraries(${PROJECT_NAME} winmm.lib)
-endif()

+ 1 - 1
include/pocketpy/interpreter/modules.h

@@ -14,4 +14,4 @@ void pk__add_module_enum();
 void pk__add_module_linalg();
 void pk__add_module_linalg();
 void pk__add_module_array2d();
 void pk__add_module_array2d();
 
 
-void pk__add_module_win32();
+void pk__add_module_conio();

+ 2 - 0
include/typings/conio.pyi

@@ -0,0 +1,2 @@
+def _kbhit() -> int: ...
+def _getch() -> int: ...

+ 0 - 10
include/typings/line_profiler.pyi

@@ -1,10 +0,0 @@
-from typing import Callable
-
-class LineProfiler:
-    def __init__(self): ...
-
-    def add_function(self, func: Callable) -> None: ...
-
-    def runcall(self, func: Callable, *args) -> None: ...
-
-    def print_stats(self) -> None: ...

+ 0 - 4
include/typings/win32.pyi

@@ -1,4 +0,0 @@
-def _kbhit() -> int: ...
-def _getch() -> int: ...
-
-def PlaySoundA(pszSound: str, hmod: int, fdwSound: int) -> bool: ...

+ 1 - 2
src/interpreter/vm.c

@@ -216,8 +216,7 @@ void VM__ctor(VM* self) {
     pk__add_module_traceback();
     pk__add_module_traceback();
     pk__add_module_enum();
     pk__add_module_enum();
 
 
-    // add win32 module
-    pk__add_module_win32();
+    pk__add_module_conio();
 
 
     // add python builtins
     // add python builtins
     do {
     do {

+ 128 - 0
src/modules/conio.c

@@ -0,0 +1,128 @@
+#include "pocketpy/pocketpy.h"
+#include <stdlib.h>
+
+#if PY_SYS_PLATFORM == 0
+
+#include <windows.h>
+#include <conio.h>
+
+#elif PY_SYS_PLATFORM == 3 || PY_SYS_PLATFORM == 5
+
+#include <stdio.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <string.h>
+
+// 保存原始终端设置
+static struct termios orig_termios;
+static bool orig_termios_set;
+
+// 还原终端设置
+static void reset_terminal_mode() { tcsetattr(0, TCSANOW, &orig_termios); }
+
+// 设置终端为非阻塞模式
+static void set_conio_terminal_mode_if_needed() {
+    if(orig_termios_set) return;
+    struct termios new_termios;
+
+    // 获取当前终端设置
+    tcgetattr(0, &orig_termios);
+    memcpy(&new_termios, &orig_termios, sizeof(new_termios));
+
+    // 禁用缓冲和回显
+    new_termios.c_lflag &= ~(ICANON | ECHO);
+    tcsetattr(0, TCSANOW, &new_termios);
+
+    atexit(reset_terminal_mode);
+    orig_termios_set = true;
+}
+
+// 检查是否有按键按下
+int _kbhit() {
+    set_conio_terminal_mode_if_needed();
+
+    struct termios term;
+    int oldf;
+    int ch;
+    int old_flags;
+
+    // 获取终端设置
+    tcgetattr(0, &term);
+    oldf = term.c_lflag;
+    term.c_lflag &= ~(ICANON | ECHO);
+    tcsetattr(0, TCSANOW, &term);
+
+    // 设置文件描述符为非阻塞
+    old_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
+    fcntl(STDIN_FILENO, F_SETFL, old_flags | O_NONBLOCK);
+
+    // 检查是否有输入
+    ch = getchar();
+
+    // 还原文件描述符设置
+    fcntl(STDIN_FILENO, F_SETFL, old_flags);
+
+    // 还原终端设置
+    term.c_lflag = oldf;
+    tcsetattr(0, TCSANOW, &term);
+
+    if(ch != EOF) {
+        ungetc(ch, stdin);
+        return 1;
+    }
+
+    return 0;
+}
+
+// 获取一个字符
+int _getch() {
+    set_conio_terminal_mode_if_needed();
+
+    int ch;
+    struct termios oldt, newt;
+
+    // 获取当前终端设置
+    tcgetattr(STDIN_FILENO, &oldt);
+    newt = oldt;
+
+    // 禁用缓冲和回显
+    newt.c_lflag &= ~(ICANON | ECHO);
+    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
+
+    // 读取字符
+    ch = getchar();
+
+    // 还原终端设置
+    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
+
+    return ch;
+}
+#endif
+
+#if PK_IS_DESKTOP_PLATFORM && PK_ENABLE_OS
+static bool conio_kbhit(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(0);
+    int ret = _kbhit();
+    py_newint(py_retval(), ret);
+    return true;
+}
+
+static bool conio_getch(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(0);
+    int ret = _getch();
+    py_newint(py_retval(), ret);
+    return true;
+}
+
+void pk__add_module_conio() {
+    py_Ref mod = py_newmodule("conio");
+    py_bindfunc(mod, "_kbhit", conio_kbhit);
+    py_bindfunc(mod, "_getch", conio_getch);
+}
+
+#else
+
+void pk__add_module_conio() {}
+
+#endif

+ 0 - 47
src/modules/win32.c

@@ -1,47 +0,0 @@
-#include "pocketpy/pocketpy.h"
-
-#if defined(_WIN32) && defined(PK_MODULE_WIN32)
-
-#include <windows.h>
-#include <conio.h>
-
-static bool win32__kbhit(int argc, py_Ref argv) {
-    PY_CHECK_ARGC(0);
-    int ret = _kbhit();
-    py_newint(py_retval(), ret);
-    return true;
-}
-
-static bool win32__getch(int argc, py_Ref argv) {
-    PY_CHECK_ARGC(0);
-    int ret = _getch();
-    py_newint(py_retval(), ret);
-    return true;
-}
-
-static bool win32_PlaySoundA(int argc, py_Ref argv) {
-    PY_CHECK_ARGC(3);
-    PY_CHECK_ARG_TYPE(0, tp_str);
-    PY_CHECK_ARG_TYPE(1, tp_int);
-    PY_CHECK_ARG_TYPE(2, tp_int);
-    const char* pszSound = py_tostr(argv);
-    py_i64 hmod = py_toint(py_arg(1));
-    py_i64 fdwSound = py_toint(py_arg(2));
-    int ret = PlaySoundA(pszSound, (HMODULE)hmod, fdwSound);
-    py_newbool(py_retval(), ret);
-    return true;
-}
-
-#endif
-
-
-void pk__add_module_win32() {
-#if defined(_WIN32) && defined(PK_MODULE_WIN32)
-    py_Ref mod = py_newmodule("win32");
-
-    py_bindfunc(mod, "_kbhit", win32__kbhit);
-    py_bindfunc(mod, "_getch", win32__getch);
-
-    py_bindfunc(mod, "PlaySoundA", win32_PlaySoundA);
-#endif
-}