Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (480)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (546)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Sequential and multiple method calls? (Command/Runnable/Enums)  (Read 1035 times)
0 Members and 1 Guest are viewing this topic.
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Posted 2013-08-22 18:43:57 »

So I was watching someone else program in actionscript. And I have never really had a desire or great use to use function pointers( pass a method as an argument) and they were using an array to pass special effects to some graphic/text things, the special effects were usually simple 2-5 line function/methods and it just seemed so easy, without my typical method of having a ton of boolean statements everywhere.

However after seeing them do some things quite conveniently, I was hoping to find an alternative.
In my case I just wanted to be able to do it to handle certain 'effects'  that I can add/remove from an update/scripts list

Here is just a random limited example.

logo
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
scripts.add(new fade());      
}

ArrayList<functionPointer> scripts = new ArrayList<functionPointer>();
public float alpha;
   
public class fadeOut implements functionPointer{
   @Override
   public void execute() {
      alpha=-.01f;
   }
}
public class fade implements functionPointer{
   @Override
   public void execute() {
      alpha+=.01f;
      if(alpha >= 1){
         scripts.remove(this);
         scripts.add(new fadeOut());
      }
   }
}

public void someUpdateFunction(){
   for(functionPointer fp : scripts){
      fp.execute();
   }
}


Then of course
functionPointer.java
1  
2  
3  
public interface functionPointer {
   public void execute();
}



Would there be a better way of doing this?

Essentially whats a good way to embed possibly sequential and/or concurrent methods to be utilized by the same class in several areas that need to come and go.
Alternatively, I could have a lot of embedded if/else and boolean statements and other conditionals all over the place.



Maybe there is something out there that would work a lot better that I just don't know about? (Some sort of event/script/callback manager) thingy?




"Experience is what you get when you did not get what you wanted"
Offline Mac70
« Reply #1 - Posted 2013-08-22 18:48:40 »

Java 8 will have built-in support for passing methods as arguments. Wink

Check out my Devblog! Smiley
Online BurntPizza
« Reply #2 - Posted 2013-08-22 18:51:54 »

Your method is appropriate, it is called the Command Pattern.

Java 8 will have built-in support for passing methods as arguments. Wink

Really?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #3 - Posted 2013-08-22 18:55:37 »

Aha!  Brilliant thanks!

http://en.wikipedia.org/wiki/Command_pattern#Java

Command is a better name the functionPointer Cheesy

"Experience is what you get when you did not get what you wanted"
Offline actual

JGO Coder


Medals: 23



« Reply #4 - Posted 2013-08-22 19:04:24 »


Yup. They are calling them Lambda Expressions.

Java Dzone article
Oracle tutorial.

Online BurntPizza
« Reply #5 - Posted 2013-08-22 19:06:53 »

Yup. They are calling them Lambda Expressions.

Well Lambda Expressions are nothing new, although incorporating them into Java will be interesting.
Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #6 - Posted 2013-08-22 19:13:09 »

Use enums. Enums can have abstract methods, in which case you define one method per enum value. Or you can use enums in a switch statement (inside an enum method or outside the enum class.)

Your work will be much easier with enums because you can name your effects. (Glow, Fade, Sparkle, Shrink, Explode, etc.) If you want to modify an effect you change it in one place instead of half a dozen. Your IDE will also support enums better. You can use autocompletion, usage searches, and refactoring tools. The IDE will warn your of missing case statements. And you can configure it to automatically create a full switch, case, break, default block.

Edit: Unlike interface instances they can be compared using ==, do not create garbage, and can be used with the singleton pattern. The only downside is they cannot be created dynamically and everything has to appear in the same file. (Unless they call a static function in another class.) The latter could be addressed using a tool that merges several text files. The former is not often useful but maybe could be done using a class loading hack, but the dynamic part defeats the benefits of non-dynamic IDE features.

Edit 2: Enums can implement interfaces. I think that means you could create separate class files, do dynamic class loading, and treat them like Objects. If you wanted to use it in a switch you would have to cast it. (Or use int constants)
Offline sproingie

JGO Kernel


Medals: 202



« Reply #7 - Posted 2013-08-22 19:45:20 »

Your "functionpointer" interface already exists in the forms of Runnable and Callable, both of which will benefit from some syntax sugar in 1.8.  But if you have a fixed set of commands, you're better off using an Enum.  There's nothing stopping you from making your enum implement an interface itself if you think you might need custom implementations, which is how I did BlendMode in JCOD
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #8 - Posted 2013-08-22 21:03:37 »

So I have been trying to use enums, however I am having issues with variable access

When I make the enum and trying to access the classes variable, lets say alpha, x, or y.  IT wants it to be a static access, however I can't do that given how I want to set the things up. Since there might be multiple instances of the class.


Any suggestions?  Because I like the style/appearance enums has, especially with the reduction of garbage.


edit: or how do I force the enum inside my class to not be static?

"Experience is what you get when you did not get what you wanted"
Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #9 - Posted 2013-08-22 21:23:17 »

I've never seen the error you are talking about. Are you using enums as a singleton with a state? You want the enum to represent the method to perform on the data and not to store data itself. Pass the data as a parameter. It should work, otherwise you would not be able to use enum's equals method. Enum has very strange syntax, it's possible you made a mistake. Post the code if you want.

Edit:

Did you make the enum an inner class of something else? You won't be able to use it with other classes if you make it non-static and if you make it static it will give you the same error that a static inner class accessing an outer class. (There is no OuterClass.this reference for static classes while there is for non-static inner classes. Static inner classes require a reference since it is not implicit.)

I don't recommend using innner classes for this purpose.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline lcass
« Reply #10 - Posted 2013-08-22 22:20:05 »

I was taking a look at this earlier actually Im not sure but I think you can do it with the .getClass().getMethods(); function aswell.
Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #11 - Posted 2013-08-22 22:55:16 »

You could, but it creates more than one object (which is more than zero), there is no parameter type checking on invoke, it's slower, and method.invoke() is less clear than interface.method().
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #12 - Posted 2013-08-23 03:15:55 »

So while this isn't exactly the use case I wnat. I think its a good enough example and fully functioning one.

main GdxGame file
http://pastebin.com/8H0ewZnj

Logo.java
http://pastebin.com/AZTgzWbD
First I have it run 2 things pseudo-concurrently,  then they are both removed, and 1 is called at the end of one of them to run indefinitely until that object is removed.


The only other solution I can think of is creating a whole other set of classes and an entire system which depends upon Logo extending or implementing certain interfaces or a base class(Entity) that has things such as alpha and position in them.
Then set up a whole system with variable input and output to handle it.
Or for the 3-4 places I want it, I just throw in a short quick semi hardcoded solution.

Either way I was trying to not have a whole other class to handle this 1 class.
I also didn't want to create an entire dynamic tween/manipulator set of classes to handle a more 'robust' system (which although would be great longer term) I am just looking to apply it to a few small areas.


If there is a better/simpler way of setting this up, then my provided example. Please let me know.



"Experience is what you get when you did not get what you wanted"
Offline Several Kilo-Bytes

Senior Member


Medals: 11



« Reply #13 - Posted 2013-08-23 21:59:44 »

Hmm... Computer programs consist of two basic units; data and code. Data is accessed statically via named variables and named functions and dynamically through pointers and function pointers. In object oriented programming, the things called objects are bundles of data with operations associated with them. Objects combine data and code into one variable or pointer.

If you have N objects and 1 effect but the effect require extra state data which is not stored in the original objects, you still need N places to store the extra state data even though there is only 1 effect. Function pointers are stateless.
There are three ways to fix it.
1) Take the state data out of the effect and put it into the object it affects. (Use one object and one function pointer.)
2) Leave the effect state data in the Effect object. Reference the affected object int the effect object and vica versa. (Use one additional object per effect/entity pair.)
3) Merge the state data for all effects into the super class of the class it affects. (Use one object and bad design practices.)

To simplify the following definitions, assume that static variables are not used. (Mutable global variables are bad practice anyways.)
Data variables store values and do nothing on their own.
Functions represent code. They do nothing without data to work on.
Objects store both of the above.

Objects have an implicit this reference. If you rely on having that reference as your code does, you are using your class as an object not a "function pointer".

1  
2  
3  
4  
5  
public enum Effect implements Whatever
{
// public abstract void doEffect(); // Wrong
public abstract void doEffect(Object affectedObject); // Right
}


1  
2  
3  
4  
5  
public class Thing
{
public abstract void doEffects(); // Right
public abstract void doEffect(EffectType effect); // Right
}
Offline sproingie

JGO Kernel


Medals: 202



« Reply #14 - Posted 2013-08-23 23:48:58 »

I wouldn't say it's always as strict as that, since an object also represents a static closure, which is something you can and do determine dynamically.  In that case, affectedObject would be passed in via the constructor.  Of course if your Effects are enums, then yes. you are going to have to pass affectedObject in as a parameter, since your instances of Effect are all statically defined (enumerated) beforehand. 
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

atombrot (22 views)
2014-08-19 09:29:53

Tekkerue (22 views)
2014-08-16 06:45:27

Tekkerue (21 views)
2014-08-16 06:22:17

Tekkerue (12 views)
2014-08-16 06:20:21

Tekkerue (19 views)
2014-08-16 06:12:11

Rayexar (57 views)
2014-08-11 02:49:23

BurntPizza (37 views)
2014-08-09 21:09:32

BurntPizza (29 views)
2014-08-08 02:01:56

Norakomi (36 views)
2014-08-06 19:49:38

BurntPizza (66 views)
2014-08-03 02:57:17
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!