There is a RenPy-based game that uses custom Python classes for some game objects.
Recently we renamed some modules and classes as part of refactoring. This broke loading of old game saves because Pickle can't find classes.
The Pickle itself supports a mechanism to properly handle situation with class renaming: https://wiki.python.org/moin/UsingPickle/RenamingModules
However I can't apply this code to a RenPy game because save/load process is controlled by RenPy in it's loadsave.py module. Is there a way to fix loading without patching RenPy code? Any monkeypatch ideas?
What I usually do when I move stuff around in Ren'Py is to just create an alias from the old name of the class to the new name. That's enough for pickle - it looks up the old name, and creates a class with the new name.
For example, if I had
class OldClass(object):
pass
and wanted to rename it to NewClass, I would have the code:
class NewClass(object):
pass
OldClass = NewClass
This works across modules, too.
Related
I want to create a Processing library that adds a single function to Processing. A single command. How do I do this?
So I want to be able to write on Processing this:
void setup() {
drawMyCustomShape()
}
In a way that drawMyCustomShape will be on my custom library implementation.
Thanks!
Note: this question is not about creating a new library in processing. Is about creating a library that exports one new command (so you can using without caring of the container class instance).
First of all, are you sure you really need to create an entire library? You could just add that class to your sketch without needing to deploy it as a library. If you're worried about clutter, just put it in its own tab.
If you really need to create a library, then there are three tutorials that you need to read:
Library Overview
Library Basics
Library Guidelines
But basically, you need to create a Java project (in an IDE like eclipse, or with a basic text editor and the command line) that uses Processing as a library. That's where you'd put your MyLibrary class. You'd then export it as a .jar file, and then import that .jar file into Processing. You would then be able to use your class exactly like you can use any other Processing library.
Your proposed setup has some other issues (how are you going to access the sketch variable from the static function?), but I'd suggest treating them as separate questions after you get the basics in place.
It sounds like you are actually looking to create your own extension of the Processing library, as in actually change the core jar file.
You can extend the actual Processing library by forking off of its main branch on Github. By writing your function drawMyCustomShape into the actual core in the forked version, you can then build the Processing Development Environment from your copy of the code. Using that particular copy of the PDE, you could do what you're describing.
Once you compile this build, you could actually distribute this copy of the PDE to your college students. They would be able to use your function as if nothing were changed. (I'm guessing that this is for an intro-level class at the college level, so that's why you would have to hide implementation from your students?)
Here's some links to get you started:
Processing github
Instructions for building the PDE from source
So, finally I found the most adequate answer for my case.
The solution for this is to implement a new Processing Mode that extends the builtin Java Mode. To include static members to the main processing program you will need to add a new static import to the ones that processing adds to your code.
You can do this by forking the Mode Template for 3.0 that #joelmoniz created from #martinleopold:
https://github.com/joelmoniz/TemplateMode/tree/3.0-compatibility
There is a good tutorial here:
http://pvcresin.hatenablog.com/entry/2016/03/17/210135
Why is the most adequate solution? : I think this is the best way to achieve new static methods in processing code and ensure an easy distribution! You just have to set the mode folder in your sketchbook/modes folder. If I were to fork processing it would be a big deal to prepare distributions for all operative systems and also to keep update with main project.
My particular solution:
To add my static imports into Processing I implemented a custom mode where I overrode the PdePreprocessor class which wraps the processing code with all the Java procesing code. So, the idea was to add more imports to the imports that the PdePreprocessor generates on the generated Java source.
In my custom PdePreprocessor I overrode the getCoreImports method to add my custom methods. I did this here because I consider the new imports are part of the core of my custom mode. You could also achieve this by overriding writeImports method.
In order to use my PdePreprocessor implementation I had to overrode the following classes:
Commander
JavaBuild
JavaEditor
JavaMode
JavaEditor
I had to implement a new JavaBuild which preprocesses the Sketch with my custom PdePreprocessor. And also use my custom JavaBuild in all the places where the Processing Java Mode instances the build class. Please share with us if there is a better way to do what I did.
Here is the github for my solution: http://github.com/arypbatista/processing-inpr/
Firstly, my environment. My question is if it's possible to do so using Flash Professional and not Flex, FlashBuilder or the like (I don't have those environments at the moment).
Here is the thing: we have several .fla files with a Document Class set. The .as file with the class is shared with all those .fla files, so all them have this same class set as their Document Class. The point is that because of that the Class is compiled into each generated .swf files, and as result any changes made to the Class would require all the .fla files to be recompiled.
After some research I found out about RSLs. But I'd like to know if it's possible to have the class as RSL while also having it as Document Class for each file? It would ease stuff because in case a change needs to be done in the class we wouldn't need to recompile each file, or regenerate each .swf files.
Aditionally, if it's possible, how could I implement a RSL through Flash Professional? All the documentation I have found shows that through Flex and others.
Please let me know if I wasn't clear enough.
As already pointed out, you cannot use a RSL with a document class. However, you can put classes in an RSL and load those at runtime likely achieving what you desire.
Here is a very simple example:
1. Create the RSL assets:
Let's say you have a class that changes from time to time and you want to load it's functionality at runtime:
//TestyMcTestFace.as
package {
public class TestyMcTestFace {
public static function go():String{
return "I'm Testy McTestFace";
}
}
}
So, what you can do, is make a new AS3 project in FlashPro/AdobeAnimate CC. Link up your class file so your project finds it (in this case I just put my TestyMcTestFace.as in the same directory as the new .fla I created).
Put a reference in the timeline code to the class(es) you want included. Without this reference the class will not get exported in the resulting swc/swf.
So for this case, I have a new AS3 project with just one line on the first frame of the timeline:
TestyMcTestFace;
Now, go to your publish settings, and make it so only Flash (swf) and SWC are checked.
Publish this new project (you now have a swf/swc you can use as a RSL for other applications).
2. Setup your other applications to use the swf/swc as a RSL.
In your existing flash project, go to the 'Advanced Actionscript Settings' (click the wrench icon next "Actionscript 3.0" in the publish settings).
Click the library path tab, click the plus button, then click the "Browse To SWC File" button (currently it's an icon with the flash 'f' in it). Find your swc file from the previous step.
Now, with your new entry highlighted, click the info icon (linkage options). Change it from "Merged into code" to "RSL". Then add a path to the swf file (where it will be when this application runs).
Now, in your application, you can reference classes from the RSL. So if we do this:
trace(TestyMcTestFace.go());
You should get the output "I'm Testy McTestFace".
FlashPro will automatically load the RSL for you. Be aware though, that if you aren't letting flash preload your app automatically, it won't be available right away.
If you changed and re-exported the swc/swf from step one, those changes should be reflected when you run your existing swf again (no recompiling necessary).
Caveats:
Be careful with code in RSL's. It's easy to get clashing classes. As a best practice, only put code that is completely standalone/de-coupled into RSL's. Code that has lots of imports should be avoided. It's also best if you don't reference classes with same names in your compiled swf's that you are loading the RSL's.
Also keep in mind that RSL's can have sanbox/security restrictions if not coming from the same domain.
not possible, RSL is only meant for runtime sharing not for compile time sharing which you need to access the class.
First thing is, one class is not that much in term of size so there's not really a need to make it unique a sharable between swfs.
Now you affirm that all swfs would have to be recompiled if you make any change but that's not actually accurate since only one class definition can exist in one given runtime. The first swf running is by default the one loading the class definition, all the loaded swfs following would have their class definition discarded by default so no you don't have to recompile them in theory.
So to resume yes you have to recompile all swfs if you make major changes to the class but not for minor changes. But that situation is symptomatic to your app design which might not be the most efficient and logical.
i'am trying to use components from another module, but is not working.
Look what i have:
I have my project, its an app to convert files, and its working everything is ok. Now i want to change the interface... for that i cloned a github repository thats is a project with the components that i want to use, and imported it as a module. (should i import as a module or as a project?)
Everything great till now, but when i try to use the components from the module i cant find the classes or even the module...
Any suggestions?
You should add your imported sources as a new module (let's call it B), then you should add a dependency from your original module A to your module B in order to use its code.
See this page on how to configure module dependencies.
I'm making a game and I an in-game editor that is able to create entities on the fly (rather than hard coding them). I'm using a component-aggregation model, so my entities are nothing but a list of components.
What would be the best way to obtain or generate a list of components? I really don't want to have to manually add entries for all possible components in some giant registerAllComponents() method or something.
I was thinking maybe somehow with reflection via either the knowledge that all components inherit from the base Component class, or possibly via custom metatags but I haven't been able to find ways to get a list of all classes that derive from a class or all classes that have custom metatags.
What sort of options am I left with?
Thanks.
For a project I did once, we used a ruby script to generate an AS file containing references to all classes in a certain package (ensuring that they were included in the compilation). It's really easy considering that flash only allows classes with the same name as the file it's in, so no parsing of actual code needed.
It would be trivial to also make that add an entry to a dictionary (or something similar), for a factory class to use later.
I believe it's possible to have a program execute before compilation (at least in flashdevelop), so it would not add any manual work.
Edit: I added a basic FlashDevelop project to demonstrate. It requires that you have ruby installed.
http://dl.dropbox.com/u/340238/share/AutoGen.zip
Unfortunately, there is no proper way of getting all loaded classes or anything like that in the Flash API right now. So finding all sub-classes of Component is out, inspecting all classes for a specific meta tag is out as well.
A while ago I did run into a class/function that inspected the SWF's own bytecode upon loading to retrieve all contained classes. That's the only option for this kind of thing. See this link and the bottom of my post.
So, you're left with having to specify a list of component classes to pick from.
One overly complicated/unfeasible option that comes to mind is creating an external tool that searches your source folders, parses AS3 code and determines all sub-classes of Component, finally producing a list in some XML file. But that's not a task for the faint-hearted...
You can probably think of a bunch of manual solutions yourself, but one approach is to keep an accessible Array or Vector.<Class> somewhere, for example:
public static const COMPONENT_LIST:Vector.<Class> = Vector.<Class>( [
CollisionComponent,
VisualComponent,
StatsComponent,
...
...
] );
One advantage over keeping a list of String names, for example, would be that the component classes are guaranteed to be compiled into your SWF.
If the classes aren't explicitly referenced anywhere else in your code, they are not compiled. This might occur for a simple component which you only update() once per frame or so, and is only specified by a string in some XML file.
To clarify: You could use the code in the link above to get a list of the names of all loaded classes, then use getDefinitionByName(className) for each of them, followed by a call to describeType(classObj) to obtain an XML description of each type. Then, parsing that for the type's super-types, you could determine if it extends Component. I personally would just hardcode a list instead; it feels too messy to me to inspect all loaded classes on startup, but it's up to you.
Not sure if this is possible but I would like to reflect a swf or swc file selected by the user at runtime to find any classes that implement a certain interface. Can this be done or do you actually need a reference to the class you want to reflect using describeType();
Note - this would be done in actionscript.
Thanks,
You can inspect a swf for the classnames (Source) and then use describeType on them to find the ones which implement the interface(s). But this is probably slow. You can try to extend the getDefinitionNames code to get around the describeType and extract the needed info from the bytes...