New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Python scriptable general purpose import/export plugin #415

Merged
merged 40 commits into from Apr 20, 2013

Conversation

Projects
None yet
4 participants
@stt
Contributor

stt commented Apr 4, 2013

So, I've been sitting on this for about a year due to lack of better log output mechanism than printing to stdout, that better mechanism is now implemented as ConsoleDock.

To the uninitiated, a brief overview:

What it is

Allows adding new map filetypes as python scripts in ~/.tiled/ directory.

What it does

Map import and export with tilesets, layers and objects.
There are couple of scripts in the fork, cleanest of which at the moment is Mappy support, that could still use addition of exporting before being considered for public consumption.
A note about export; as Tiled plugins are loaded only once, some details of maps can be stored in the interpreter state while importing a map and then recalled for reintegration when exporting the map back to it's original format.

Runs on

At least Windows 7 and Linux (Ubuntu/Arch Linux)

It requires

  • Python 2.x (realistically >=2.6 which is 5y old, but no version check is done),
    Tiled of course still runs normally if no usable version of python is found

Personally I favor a system wide installation of python, but it was tested that is not needed if python27.dll (on windows) and python27.zip are copied to the Tiled installation directory (this is combined size of 3.5MB).

Adding support for 3.x was considered and doesn't look like too much work (it should even be able to be supported by the same plugin, taken that the scripts would be loaded from separate directories), but I may not have time to take this on for couple of months.

stt and others added some commits Feb 11, 2012

Exclude Python plugin project entirely when no Python is found
Signed-off-by: Samuli Tuomola <samuli.tuomola@gmail.com>
Rewrote the plugin w/o callbacks and updated scripts.
Notes:
- fotf now loads most levels with correct tilesets
- Lacks testing in windows
Added map property + tileset transparency etc bindings
Also layer/objgroup support.
Exposing tilelayer.cell classes' member "tile" produces a nasty warning
from pybindgen, seems to work so far though.
Write support fixed
Supports export only to same script that loaded the map.
Fixed windows console error output
Could've sworn it used to work without redirect on python side though.

stt added some commits Sep 18, 2012

Pass the ownership of the map object
Shouldn't try to free the wrapper yet though as layers are still owned by
it. The wrappers leak so (re)opening a lot of maps may end up consuming
more memory than actually needed, should look into this.
Anyway, it's not script writer's responsibility to manage references.
};
virtual void log(OutputType type, const QString) = 0;
};

This comment has been minimized.

@bjorn

bjorn Apr 20, 2013

Owner

This is kind of strange, because the log method is not used from Tiled but is just forced to be implemented by the plugin, and the only way for it to work is for the plugin to emit signals with a signature that you can only find in consoledock.cpp.

I think the interface is fine, but I think it should be implemented by Tiled, not by the plugin. Then, a function setLogger(LoggingInterface *) for example can be added to MapWriterInterface and MapReaderInterface. Maybe with a default implementation that does nothing, to avoid having to add that to all existing plugins (though I'm sure some existing plugins could use this interface as well).

The ConsoleDock can then implement this interface, query all map readers and writers and set itself as their logger.

@bjorn

bjorn Apr 20, 2013

Owner

This is kind of strange, because the log method is not used from Tiled but is just forced to be implemented by the plugin, and the only way for it to work is for the plugin to emit signals with a signature that you can only find in consoledock.cpp.

I think the interface is fine, but I think it should be implemented by Tiled, not by the plugin. Then, a function setLogger(LoggingInterface *) for example can be added to MapWriterInterface and MapReaderInterface. Maybe with a default implementation that does nothing, to avoid having to add that to all existing plugins (though I'm sure some existing plugins could use this interface as well).

The ConsoleDock can then implement this interface, query all map readers and writers and set itself as their logger.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Apr 20, 2013

Owner

Noticed this in the Debug Console, an error?

-- Reloading zst
TypeError: issubclass() arg 1 must be a class
Owner

bjorn commented Apr 20, 2013

Noticed this in the Debug Console, an error?

-- Reloading zst
TypeError: issubclass() arg 1 must be a class
@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Apr 20, 2013

Owner

The plugin crashes (along with Tiled), when I try to open the example map smooth.fmp included with MappyWin32 V1.4.23.

0   QMap<QString, QString>::detach  qmap.h  205 0x7fffe5f956a6  
1   QMap<QString, QString>::insert  qmap.h  562 0x7fffe5f9490a  
2   Tiled::Object::setProperty  object.h    99  0x7fffe5f94651  
3   Python::PythonPlugin::read  pythonplugin.cpp    267 0x7fffe5f9345a  
4   Tiled::Internal::MainWindow::openFile   mainwindow.cpp  579 0x52f6f0    
...

Edit: looking into this, it seems to be due to an uncaught script exception. After that it will still try to set a __script__ property on the uninitialized Tiled::Map *ret.

I've avoided this with a local change and got the script error from the console:

** Uncaught exception in script **
Traceback (most recent call last):
  File "/home/bjorn/.tiled/mappy.py", line 31, in read
    tset.loadFromImage(readtilegfx(hd, chunks['BGFX'], cmap), "")
  File "/home/bjorn/.tiled/mappy.py", line 93, in readtilegfx
    img.setPixel(tx+x, ty+y, cmap[c])
UnboundLocalError: local variable 'c' referenced before assignment
Owner

bjorn commented Apr 20, 2013

The plugin crashes (along with Tiled), when I try to open the example map smooth.fmp included with MappyWin32 V1.4.23.

0   QMap<QString, QString>::detach  qmap.h  205 0x7fffe5f956a6  
1   QMap<QString, QString>::insert  qmap.h  562 0x7fffe5f9490a  
2   Tiled::Object::setProperty  object.h    99  0x7fffe5f94651  
3   Python::PythonPlugin::read  pythonplugin.cpp    267 0x7fffe5f9345a  
4   Tiled::Internal::MainWindow::openFile   mainwindow.cpp  579 0x52f6f0    
...

Edit: looking into this, it seems to be due to an uncaught script exception. After that it will still try to set a __script__ property on the uninitialized Tiled::Map *ret.

I've avoided this with a local change and got the script error from the console:

** Uncaught exception in script **
Traceback (most recent call last):
  File "/home/bjorn/.tiled/mappy.py", line 31, in read
    tset.loadFromImage(readtilegfx(hd, chunks['BGFX'], cmap), "")
  File "/home/bjorn/.tiled/mappy.py", line 93, in readtilegfx
    img.setPixel(tx+x, ty+y, cmap[c])
UnboundLocalError: local variable 'c' referenced before assignment
@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Apr 20, 2013

Owner

I guess we need to separate the name filters for reading and writing, since at the moment there's no way for the Python plugin to avoid listing the Mappy and zSNES in Save As, even though they do not implement writing.

Owner

bjorn commented Apr 20, 2013

I guess we need to separate the name filters for reading and writing, since at the moment there's no way for the Python plugin to avoid listing the Mappy and zSNES in Save As, even though they do not implement writing.

@bjorn bjorn merged commit d3ae074 into bjorn:master Apr 20, 2013

1 check passed

default The Travis build passed
Details
@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Apr 20, 2013

Owner

@stt As you can see I've merged your branch and simply applied the fix for the potential crash on top (commit 5b290f4). I figured we can solve the issues I found after merging.

So, I hope you will consider my proposal to change around the way the LoggingInterface is used, and I think I will try to find some time to fix the conflict between readable and writable name filters eventually.

Owner

bjorn commented Apr 20, 2013

@stt As you can see I've merged your branch and simply applied the fix for the potential crash on top (commit 5b290f4). I figured we can solve the issues I found after merging.

So, I hope you will consider my proposal to change around the way the LoggingInterface is used, and I think I will try to find some time to fix the conflict between readable and writable name filters eventually.

@stt

This comment has been minimized.

Show comment
Hide comment
@stt

stt Apr 20, 2013

Contributor

Yep, the log interface change you proposed sounds logical.
Think I noticed the crash but forgot to apply a fix, thanks for that.
About the scripts, most of them aren't up to date since I've been wondering should they be hosted somewhere outside of tiled, except for some simple one that demonstrates/tests all the features?
Also a plugin/script version check is something that'd be good to have.

Contributor

stt commented Apr 20, 2013

Yep, the log interface change you proposed sounds logical.
Think I noticed the crash but forgot to apply a fix, thanks for that.
About the scripts, most of them aren't up to date since I've been wondering should they be hosted somewhere outside of tiled, except for some simple one that demonstrates/tests all the features?
Also a plugin/script version check is something that'd be good to have.

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Apr 20, 2013

Owner

I think it's fine that those scripts live alongside Tiled, unless you would personally prefer to maintain them elsewhere.

As for the plugin/script version check, feel free to add one. Sounds like a good idea indeed.

Owner

bjorn commented Apr 20, 2013

I think it's fine that those scripts live alongside Tiled, unless you would personally prefer to maintain them elsewhere.

As for the plugin/script version check, feel free to add one. Sounds like a good idea indeed.

@devnewton

This comment has been minimized.

Show comment
Hide comment
@devnewton

devnewton Oct 14, 2013

Contributor

A system wide Python installation is fine for developers and most linux users, but a little hard to provides for artists on OS without packaging system...

Contributor

devnewton commented Oct 14, 2013

A system wide Python installation is fine for developers and most linux users, but a little hard to provides for artists on OS without packaging system...

@josephharding

This comment has been minimized.

Show comment
Hide comment
@josephharding

josephharding Dec 16, 2013

Hey guys - just wondering where this feature is in the Tiled release schedule. I'd definitely like to be able to write my own export script in python for Tiled. Thanks!

josephharding commented Dec 16, 2013

Hey guys - just wondering where this feature is in the Tiled release schedule. I'd definitely like to be able to write my own export script in python for Tiled. Thanks!

@bjorn

This comment has been minimized.

Show comment
Hide comment
@bjorn

bjorn Dec 16, 2013

Owner

@gyrospike To use this feature you need to use a daily build, since it was added after Tiled 0.9. Not all daily builds have Python support enabled though.

Owner

bjorn commented Dec 16, 2013

@gyrospike To use this feature you need to use a daily build, since it was added after Tiled 0.9. Not all daily builds have Python support enabled though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment