浏览代码

Merge pull request #137 from Unity-Technologies/fix_window_instance_null_crash

Fix window instance null crash
/siyaoH-1.17-PlatformMessage
GitHub 3 年前
当前提交
446b1d71
共有 8 个文件被更改,包括 51 次插入1 次删除
  1. 12
      README-ZH.md
  2. 18
      README.md
  3. 8
      com.unity.uiwidgets/Runtime/ui/window.cs
  4. 4
      engine/src/lib/ui/ui_mono_state.cc
  5. 2
      engine/src/lib/ui/ui_mono_state.h
  6. 3
      engine/src/lib/ui/window/window.cc
  7. 4
      engine/src/runtime/mono_state.cc
  8. 1
      engine/src/runtime/mono_state.h

12
README-ZH.md


如果想在runtime选择是否debug,请修改文件```com.unity.uiwidgets/com.unity.uiwidgets/Runtime/foundation/debug.cs```中的```static bool debugEnableAtRuntimeInternal```
## 使用Window Scope保护外部调用
如果您在调试时遇到 `AssertionError: Window.instance is null` 或者在调用 `Window.instance` 时得到空指针, 那么您需要
使用以下方式来保护您的调用,使之可以在正确的Isolate上执行回调逻辑:
```csharp
using(Isolate.getScope(the isolate of your App)) {
// code dealing with UIWidgets,
// e.g. setState(() => {....})
}
```
通常,在您使用外部事件,例如来自UIWidgets之外的输入事件、网络传输回调事件时需要做这样的处理。具体的您可以参考我们的 HttpRequestSample 这个样例中的写法。需要注意的是,一般情况下您在UIWidgets框架的内部调用 (如 `Widget.build, State.initState...`)中不需要额外采取上述保护措施。
## 学习
#### 教程

18
README.md


If you want to change different mode in runtime, please modify the file “com.unity.uiwidgets/com.unity.uiwidgets/Runtime/foundation/debug.cs” by making “static bool debugEnableAtRuntimeInternal” to true or false. Note that the value is set to false by default.
## Using Window Scope
If you see the error `AssertionError: Window.instance is null` or null pointer error of `Window.instance`,
it means the code is not running in the window scope. In this case, you can enclose your code
with window scope as below:
```csharp
using(Isolate.getScope(the isolate of your App)) {
// code dealing with UIWidgets,
// e.g. setState(() => {....})
}
```
This is needed if the code is in methods
not invoked by UIWidgets. For example, if the code is in `completed` callback of `UnityWebRequest`,
you need to enclose them with window scope.
Please see our HttpRequestSample for detail.
For callback/event handler methods from UIWidgets (e.g `Widget.build, State.initState...`), you don't need do
it yourself, since the framework ensure it's in window scope.
## Learn
#### Samples

8
com.unity.uiwidgets/Runtime/ui/window.cs


public static Window instance {
get {
GCHandle gcHandle = (GCHandle) Window_instance();
IntPtr ptr = Window_instance();
if (ptr == IntPtr.Zero) {
D.assert(false, () => "AssertionError: Window.instance is null. Please enclose your code with window scope (detailed examples can be found in the README file)");
return null;
}
GCHandle gcHandle = (GCHandle) ptr;
return (Window) gcHandle.Target;
}
}

4
engine/src/lib/ui/ui_mono_state.cc


return static_cast<UIMonoState*>(MonoState::Current());
}
bool UIMonoState::EnsureCurrentIsolate() {
return MonoState::EnsureCurrentIsolate();
}
void UIMonoState::SetWindow(std::unique_ptr<Window> window) {
window_ = std::move(window);
}

2
engine/src/lib/ui/ui_mono_state.h


public:
static UIMonoState* Current();
static bool EnsureCurrentIsolate();
Window* window() const { return window_.get(); }
const TaskRunners& GetTaskRunners() const;

3
engine/src/lib/ui/window/window.cc


}
UIWIDGETS_API(Mono_Handle) Window_instance() {
if (!UIMonoState::EnsureCurrentIsolate()) {
return nullptr;
}
return UIMonoState::Current()->window()->mono_window();
}

4
engine/src/runtime/mono_state.cc


return isolate_data->get();
}
bool MonoState::EnsureCurrentIsolate() {
return Mono_CurrentIsolate() != nullptr;
}
MonoState* MonoState::Current() {
auto isolate_data =
static_cast<std::shared_ptr<MonoState>*>(Mono_CurrentIsolateData());

1
engine/src/runtime/mono_state.h


static MonoState* From(Mono_Isolate isolate);
static MonoState* Current();
static bool EnsureCurrentIsolate();
std::weak_ptr<MonoState> GetWeakPtr();

正在加载...
取消
保存