Skip to content

Commit

Permalink
Merge branch 'pr/7'
Browse files Browse the repository at this point in the history
  • Loading branch information
getnamo committed Mar 18, 2018
2 parents cdeda03 + 9143890 commit b488657
Show file tree
Hide file tree
Showing 175 changed files with 7,503 additions and 2,910 deletions.
40 changes: 31 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@

# UnrealEnginePython
Embed Python in Unreal Engine 4

## Fork Notes

This fork is meant to encapsulate python + pip + scripts fully in the plugin and to allow dependency plugins to be built on top of the python plugin. Specifically it means adding automatic pip dependency resolution and automatic sys.path additions such that the resulting two plugins can be fully drag and dropped into a new project.


Teaser: https://twitter.com/KNLstudio/status/932657812466843648

# How and Why ?

This is a plugin embedding a whole Python VM (versions 3.x [the default and suggested one] and 2.7) In Unreal Engine 4 (both the editor and runtime).
Expand All @@ -25,7 +29,7 @@ Once the plugin is installed and enabled, you get access to the 'PythonConsole'

All of the exposed engine features are under the 'unreal_engine' virtual module (it is completely coded in c into the plugin, so do not expect to run 'import unreal_engine' from a standard python shell)

The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17 and 4.18.
The currently supported Unreal Engine versions are 4.12, 4.13, 4.14, 4.15, 4.16, 4.17, 4.18 and 4.19

We support official python.org releases as well as IntelPython and Anaconda distributions.

Expand Down Expand Up @@ -488,6 +492,30 @@ To access the fields of a struct just call the fields() method.

A good example of struct usage is available here: https://github.com/20tab/UnrealEnginePython/blob/master/docs/Settings.md

As structs are passed by value, you need to pay attention when manipulating structs fields that are structs by themselves:

```python
from unreal_engine.structs import TerrificStruct, DumbStruct

ts = TerrificStruct()
ts.dumb = DumbStruct(Foo=17, Bar=22)

# will not modify the original DumbStruct but a copy of it !!!
ts.dumb.Foo = 22
```

You can eventually force structs to be passed by ref (extremely dangerous as the internal C pointer could be a dangling one) using the ref() function:

```python
from unreal_engine.structs import TerrificStruct, DumbStruct

ts = TerrificStruct()
ts.dumb = DumbStruct(Foo=17, Bar=22)

# ref() will return a pointer to a struct
ts.ref().dumb.foo().Foo = 22
```

The ue_site.py file
-------------------

Expand Down Expand Up @@ -809,15 +837,9 @@ Memory management

Dealing with 2 different GC's is really challenging.

PyActor, PyPawn and PythonComponent automatically DECREF's the mapped classes. This should be enough unless you hold references
in the python modules themselves. As this would be a bad programming practice, the current approach should be safe enough.

In addition to this, every time a uobject has to return its UObject mapping, it checks for its validity and safety:
Starting from release 20180226 a new memory management system has been added (FUnrealEnginePythonHouseKeeper, available here https://github.com/20tab/UnrealEnginePython/blob/master/Source/UnrealEnginePython/Public/PythonHouseKeeper.h). This new system is completely integrated with the Unreal Engine reflection-based GC and will hold track of each ue_PyUObject abd the related UObject to understand when a python object can be safely destroyed.

```c
#define ue_py_check(py_u) if (!py_u->ue_object || !py_u->ue_object->IsValidLowLevel() || py_u->ue_object->IsPendingKillOrUnreachable())\
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state")
```
The same system works for delegates, as well as Slate.


Unit Testing
Expand Down
69 changes: 1 addition & 68 deletions Source/PythonConsole/Private/PythonConsoleModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "SDockTab.h"
#include "Editor/WorkspaceMenuStructure/Public/WorkspaceMenuStructure.h"

IMPLEMENT_MODULE( FPythonConsoleModule, PythonLog );
IMPLEMENT_MODULE( FPythonConsoleModule, PythonConsole );

namespace PythonConsoleModule
{
Expand Down Expand Up @@ -94,71 +94,4 @@ TSharedRef< SWidget > FPythonConsoleModule::MakeConsoleInputBox( TSharedPtr< SEd
TSharedRef< SPythonConsoleInputBox > NewConsoleInputBox = SNew( SPythonConsoleInputBox );
OutExposedEditableTextBox = NewConsoleInputBox->GetEditableTextBox();
return NewConsoleInputBox;
}


void FPythonConsoleModule::TogglePythonConsoleForWindow( const TSharedRef< SWindow >& Window, const EPythonConsoleStyle::Type InStyle, const FPythonConsoleDelegates& PythonConsoleDelegates )
{
bool bShouldOpen = true;
// Close an existing console box, if there is one
TSharedPtr< SWidget > PinnedPythonConsole( PythonConsole.Pin() );
if( PinnedPythonConsole.IsValid() )
{
// If the console is already open close it unless it is in a different window. In that case reopen it on that window
bShouldOpen = false;
TSharedPtr< SWindow > WindowForExistingConsole = FSlateApplication::Get().FindWidgetWindow(PinnedPythonConsole.ToSharedRef());
if (WindowForExistingConsole.IsValid())
{
WindowForExistingConsole->RemoveOverlaySlot(PinnedPythonConsole.ToSharedRef());
PythonConsole.Reset();
}

if( WindowForExistingConsole != Window )
{
// Console is being opened on another window
bShouldOpen = true;
}
}

TSharedPtr<SDockTab> ActiveTab = FGlobalTabmanager::Get()->GetActiveTab();
if (ActiveTab.IsValid() && ActiveTab->GetLayoutIdentifier() == FTabId(PythonConsoleModule::PythonLogTabName))
{
FGlobalTabmanager::Get()->DrawAttention(ActiveTab.ToSharedRef());
bShouldOpen = false;
}

if( bShouldOpen )
{
const EPythonConsoleStyle::Type PythonConsoleStyle = InStyle;
TSharedRef< SPythonConsole > PythonConsoleRef = SNew( SPythonConsole, PythonConsoleStyle, this, &PythonConsoleDelegates );
PythonConsole = PythonConsoleRef;

const int32 MaximumZOrder = MAX_int32;
Window->AddOverlaySlot( MaximumZOrder )
.VAlign(VAlign_Bottom)
.HAlign(HAlign_Center)
.Padding( 10.0f )
[
PythonConsoleRef
];

// Force keyboard focus
PythonConsoleRef->SetFocusToEditableText();
}
}


void FPythonConsoleModule::ClosePythonConsole()
{
TSharedPtr< SWidget > PinnedPythonConsole( PythonConsole.Pin() );

if( PinnedPythonConsole.IsValid() )
{
TSharedPtr< SWindow > WindowForExistingConsole = FSlateApplication::Get().FindWidgetWindow(PinnedPythonConsole.ToSharedRef());
if (WindowForExistingConsole.IsValid())
{
WindowForExistingConsole->RemoveOverlaySlot( PinnedPythonConsole.ToSharedRef() );
PythonConsole.Reset();
}
}
}
8 changes: 1 addition & 7 deletions Source/PythonConsole/Public/PythonConsoleModule.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
// Copyright 1998-2018 20Tab S.r.l. All Rights Reserved.

#pragma once

Expand Down Expand Up @@ -33,12 +33,6 @@ class FPythonConsoleModule : public IModuleInterface
output log DLL is unloaded on the fly. */
virtual TSharedRef< SWidget > MakeConsoleInputBox( TSharedPtr< SEditableTextBox >& OutExposedEditableTextBox ) const;

/** Opens a debug console in the specified window, if not already open */
virtual void TogglePythonConsoleForWindow( const TSharedRef< SWindow >& Window, const EPythonConsoleStyle::Type InStyle, const FPythonConsoleDelegates& PythonConsoleDelegates );

/** Closes the debug console for the specified window */
virtual void ClosePythonConsole();


private:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,11 @@ void FPYRichTextSyntaxHighlighterTextLayoutMarshaller::ParseTokens(const FString
FRunInfo RunInfo(TEXT("SyntaxHighlight.PY.Normal"));
FTextBlockStyle TextBlockStyle = SyntaxTextStyle.NormalTextStyle;

#if ENGINE_MINOR_VERSION >= 18
const bool bIsWhitespace = FString(TokenText).TrimEnd().IsEmpty();
#else
const bool bIsWhitespace = FString(TokenText).TrimTrailing().IsEmpty();
#endif
if(!bIsWhitespace)
{
bool bHasMatchedSyntax = false;
Expand Down

0 comments on commit b488657

Please sign in to comment.