libgdx problems with enum using jython 2.7.2 - libgdx

I am trying to use Input.Keys.A for example but I can't import that enum. Have the sam problem with ShapeRenderer and ShapeType.
using this
from com.badlogic.gdx import InputProcessor, Input, Input$Keys
doesn't work
trying this:
from com.badlogic.gdx import InputProcessor, Input, Keys
I get unresolved import. Why is there this strange $ sign. Input.Keys and ShapeRenderer.ShapeType doesn't work. can't even render a simple rectangle because of this.

I found a workaround.
to get enums from libgdx use Class.forName() insert the whole path to the enum.
here is an example for the ShapeRenderer$ShapeType
p = Class.forName("com.badlogic.gdx.graphics.glutils.ShapeRenderer$ShapeType").getEnumConstants()
if you do
print(p)
you get an array with the enums
use it like this
sr = ShapeRenderer()
sr.begin(p[2])
to use ShapeType.Filled for example
this approach should work with every enum
used it with com.badlogic.gdx.Net$Protocol to and it worked.

Related

How to pickle function from imported module with dill

I'm trying to pickle functions with dill. I want to include the whole function and not just a reference to it. Here are my two files:
fun.py:
import dill
from foo import ppp
def qqq(me):
return me + 1
print(dill.dumps(ppp, protocol=4, recurse=True, byref=True))
print(dill.dumps(qqq, protocol=4, recurse=True, byref=True))
And foo.py
def qqq(me):
return me + 1
When I run fun.py I get the following output:
b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00\x8c\x03foo\x94\x8c\x03ppp\x94\x93\x94.'
b'\x80\x04\x95\x90\x00\x00\x00\x00\x00\x00\x00\x8c\ndill._dill\x94\x8c\x10_create_function\x94\x93\x94(h\x00\x8c\n_load_type\x94\x93\x94\x8c\x08CodeType\x94\x85\x94R\x94(K\x01K\x00K\x01K\x02KCC\x08|\x00d\x01\x17\x00S\x00\x94NK\x01\x86\x94)\x8c\x02me\x94\x85\x94\x8c\x06fun.py\x94\x8c\x03qqq\x94K\x04C\x02\x00\x01\x94))t\x94R\x94}\x94h\rNN}\x94Nt\x94R\x94.'
I want to be able to make the first line of output be more similar to the second line, and actually encapsulate the function without the need for a context when reloaded later. Is there a way to do this?
Thanks so much!
James
If the module (foo) is installed on both computers, then there should be no need to do anything but import the function. So, I'll assume the question is in regard to a module that is only installed on the first machine.
It also depends on whether the module foo is "installed" on sys.path or is just available in the current directory. See:
https://github.com/uqfoundation/dill/issues/123
If it's only available in the current directory, either use dill to pickle the file itself or use something like dill.source.getsource to extract the source of the module as a string, and then transfer the string as a "pickle" (this is what ppft does).
Generally, however, dill pickles imported functions by reference, and thus assumes they are available on both sides of the load/dump.

Scala function to Json

Can I map Scala functions to JSON; or perhaps via a different way than JSON?
I know I can map data types, which is fine. But I'd like to create a function, map it to JSON send it via a REST method to another server, then add that function to a list of functions in another application and apply it.
For instance:
def apply(f: Int => String, v: Int) = f(v)
I want to make a list of functions that can be applied within an application, over different physical locations. Now I want to add and remove functions to the list. By means of REST calls.
Let's assume I understand security problems...
ps.. If you downvote, you might as well have the decency to explain why
If I understand correctly, you want to be able to send Scala code to be executed on different physical machines. I can think of a few different ways of achieving that
Using tools for distributed computing e.g. Spark. You can set up Spark clusters on different machines and then select to which cluster you want to submit Spark jobs. There are a lot of other tools for distributed computing that might also be worth looking into.
Pass scala code as a string and compile it either within your server side code (here's an example) or by invoking scalac as an external process.
Send the functions as byte code and execute the byte code on the remote machine.
If it fits with what you want to do, I'd recommend option #1.
Make sure that you can really trust the code that you want to execute, to not expose yourself to malicious code.
The answer is you can't do this, and even if you could you shouldn't!
You should never, never, never write a REST API that allows the client to execute arbitrary code in your application.
What you can do is create a number of named operations that can be executed. The client can then pass the name of the operation which the server can look up in a Map[String, <function>] and execute the result.
As mentioned in my comment, here is an example of how to turn a case class into JSON. Things to note: don't question the implicit val format line (it's magic); each case class requires a companion object in order to work; if you have Optional fields in your case class and define them as None when turning it into JSON, those fields will be ignored (if you define them as Some(whatever), they will look like any other field). If you don't know much about Scala Play, ignore the extra stuff for now - this is just inside the default Controller you're given when you make a new Project in IntelliJ.
package controllers
import javax.inject._
import play.api.libs.json.{Json, OFormat}
import play.api.mvc._
import scala.concurrent.Future
#Singleton
class HomeController #Inject()(cc: ControllerComponents) extends AbstractController(cc) {
case class Attributes(heightInCM: Int, weightInKG: Int, eyeColour: String)
object Attributes {
implicit val format: OFormat[Attributes] = Json.format[Attributes]
}
case class Person(name: String, age: Int, attributes: Attributes)
object Person {
implicit val format: OFormat[Person] = Json.format[Person]
}
def index: Action[AnyContent] = Action.async {
val newPerson = Person("James", 24, Attributes(192, 83, "green"))
Future.successful(Ok(Json.toJson(newPerson)))
}
}
When you run this app with sbt run and hit localhost:9000 through a browser, the output you see on-screen is below (formatted for better reading). This is also an example of how you might send JSON as a response to a GET request. It isn't the cleanest example but it works.
{
"name":"James",
"age":24,
"attributes":
{
"heightInCM":187,
"weightInKG":83,
"eyeColour":"green"
}
}
Once more though, I would never recommend passing actual functions between services. If you insist though, maybe store them as a String in a Case Class and turn it into JSON like this. Even if you are okay with passing functions around, it might even be a good exercise to practice security by validating the functions you receive to make sure they're not malicious.
I also have no idea how you'll convert them back into a function either - maybe write the String you receive to a *.scala file and try to run them with a Bash script? Idk. I'll let you figure that one out.

How can I make scala's ammonite use scala.util instead of ammonite.util as default for util?

In the "official" scala REPL I can do
scala> import util.Random
scala> util.Random.nextInt
res0: Int => -306696783
but in Ammonite-REPL I get
# import util.Random
cmd3.sc:1: object Random is not a member of pack ammonite.util
import util.Random
^
Compilation Failed
So right now I have to use the scala. prefix to make it work in Ammonite:
# import scala.util.Random
# scala.util.Random.nextInt
res1: Int = 503117434
I'm kind of new to Scala so I don't get why would ammonite use a different util than the (for me) "official" util, so I would appreciate if anyone can provide a rationale for this.
And more specifically, Is there any way to make util to be scala.util instead of ammonite.util?
It's not that Ammonite is replacing a different util library for the normal Scala one, it's that the Ammonite namespace has it's own util package which has a whole bunch of methods specific to Ammonite. Perhaps it would be nicer if the developer had chosen a different name for his package, but this is not an issue specific to Ammonite. It is something you will run into all the time. When there is a clash of namespaces, your only option is to fully qualify the package name for the one you want. So what you actually did is a fine solution. You can find more about this here.
And btw, since there is no util.Random in the Ammonite package you can do this after your import--I tested and this is a cut and paste from my terminal:
# Random.nextInt
res1: Int = 1045964363
When you do actually have a collision of method names, you can find a solution here

In ST2 snippets, can $TM_CURRENT_WORD be overwritten?

For context:
I'm writing up a snippet for Python to quickly cast a variable, like so: variable_foo to str(variable_foo).
If I use $SELECTION, it works fine. But if I use $TM_CURRENT_WORD, it inserts the replacement value into the middle of the variable text, like this: variastr(variable_foo)ble_foo.
I could just keep using $SELECTION, but I'd prefer the added ease of not having to select the variable first with Ctrl+D that $TM_CURRENT_WORD would provide. Is there something I'm overlooking which makes this possible, or is $SELECTION the only way to go?
For reference, the currently functional version of the snippet: ${1:type}($SELECTION)${0}
And an alternate version: ${1:type}${SELECTION/^.*/\($0\)/g}${0}
I believe that is the intended behavior. You can use a plugin to get the behavior you want though.
import sublime_plugin
class ExpandInsertSnippetCommand(sublime_plugin.TextCommand):
def run(self, edit, contents=None, name=None):
cursors = self.view.sel()
new_cursors = []
for cursor in cursors:
new_cursors.append(self.view.word(cursor))
cursors.clear()
for cursor in new_cursors:
cursors.add(cursor)
self.view.run_command("insert_snippet", {"contents": contents, "name": name})
Rather than using the command "insert_snippet" for whatever binding you have, use "expand_insert_snippet".

Dynamically instantiate a typed Vector from function argument?

For a game I'm attempting to develop, I am writing a resource pool class in order to recycle objects without calling the "new" operator. I would like to be able to specify the size of the pool, and I would like it to be strongly typed.
Because of these considerations, I think that a Vector would be my best choice. However, as Vector is a final class, I can't extend it. So, I figured I'd use composition instead of inheritance, in this case.
The problem I'm seeing is this - I want to instantiate the class with two arguments: size and class type, and I'm not sure how to pass a type as an argument.
Here's what I tried:
public final class ObjPool
{
private var objects:Vector.<*>;
public function ObjPool(poolsize:uint, type:Class)
{
objects = new Vector.<type>(poolsize); // line 15
}
}
And here's the error I receive from FlashDevelop when I try to build:
\src\ObjPool.as(15): col: 18 Error: Access of undefined property type.
Does anybody know of a way to do this? It looks like the Flash compiler doesn't like to accept variable names within the Vector bracket notation. (I tried changing constructor parameter "type" to String as a test, with no results; I also tried putting a getQualifiedClassName in there, and that didn't work either. Untyping the objects var was fruitless as well.) Additionally, I'm not even sure if type "Class" is the right way to do this - does anybody know?
Thanks!
Edit: For clarification, I am calling my class like this:
var i:ObjPool = new ObjPool(5000, int);
The intention is to specify a size and a type.
Double Edit: For anyone who stumbles upon this question looking for an answer, please research Generics in the Java programming language. As of the time of this writing, they are not implemented in Actionscript 3. Good luck.
I have been trying to do this for a while now and Dominic Tancredi's post made me think that even if you can't go :
objects = new Vector.<classType>(poolsize);
You could go something like :
public final class ObjPool
{
private var objects:Vector.<*>;
public function ObjPool(poolsize:uint, type:Class)
{
var className : String = getQualifiedClassName(type);
var vectorClass : Class = Class(getDefinitionByName("Vector.<" + className + ">"));
objects = new vectorClass(poolsize);
}
}
I tried it with both int and a custom class and it seems to be working fine. Of course you would have to check if you actually gain any speed from this since objects is a Vector.<*> and flash might be making some implicit type checks that would negate the speed up you get from using a vector.
Hope this helps
This is an interesting question (+1!), mostly because I've never tried it before. It seems like from your example it is not possible, which I do find odd, probably something to do with how the compiler works. I question why you would want to do this though. The performance benefit of a Vector over an Array is mostly the result of it being typed, however you are explicitly declaring its type as undefined, which means you've lost the performance gain. So why not just use an array instead? Just food for though.
EDIT
I can confirm this is not possible, its an open bug. See here: http://bugs.adobe.com/jira/browse/ASC-3748 Sorry for the news!
Tyler.
It is good you trying to stay away from new but:
Everything I have ever read about Vector<> in actionscript says it must be strongly typed. So
this shouldn't work.
Edit: I am saying it can't be done.
Here see if this helps.
Is it possible to define a generic type Vector in Actionsctipt 3?
Shot in the dock, but try this:
var classType:Class = getDefinitionByName(type) as Class;
...
objects = new Vector.<classType>(poolsize); // line 15
drops the mic
I don't really see the point in using a Vector.<*>. Might as well go with Array.
Anyhow, I just came up with this way of dynamically create Vectors:
public function getCopy (ofVector:Object):Object
{
var copy:Object = new ofVector.constructor;
// Do whatever you like with the vector as long as you don't need to know the type
return copy;
}