Java Game Design Class Loading - java

I'm building an RPG with JavaFX and need to get some advice from the experts.
What is the proper way to load certain resources? I'm not talking about images and sound, that part is easy. I'm talking about classes. For instance; I have like some odd 400+ abilities that you can activate. I have a separate class for each ability (or arte as I call them). To access this ability I want to be able to call
Data.getArte(idOfArte);
and this should return an object of type Arte. All of the artes have a separte class file.
There are other resources that are this way as well like Heroes, Enemies, and such. What would be the best way to load and call these resources for use? Is there a better way of doing this?
Edit: I'm also very concerned with performance.

A more efficient approach might be to use Entity Component System or at least borrow the composition design. This allows you to have a single concrete class, say Ability, that will contain generic fields common to all abilities, e.g. skill points cost, duration of ability, target types, activation types, etc. Then you would have a component for each special value you need to add and a control for each special behavior you need to add to that generic ability. Example:
Ability ability = new Ability();
ability.addComponent(new DurationComponent(double seconds)); // specify how long effect lasts
ability.addControl(new DamagingControl(int damage, Object targetType, etc.)); // so ability can damage
ability.addControl(new ElementAugmentingControl(Element element, Object weapon/armor, etc.)); // so ability can change status effects / elements
This should give you the idea of composition. Based on the common behavior of your abilities, you should end up with about 10-30 classes, while your 400 abilities simply become configurations of the base generic ability. To give you an example here's an RPG with roughly 100 abilities (skills) which are implemented as 6 classes. The same design can also be used with any game items / characters.
As for object creation you can do:
public static final int ABILITY_ID_SOME_NAME = 1000;
ability.addComponent(new IDComponent(ABILITY_ID_SOME_NAME));
Then each of your abilities could be a part of a global data store, where only ability prototypes are stored:
Ability ability = DataStore.getByID(ABILITY_ID_SOME_NAME).clone();
Alternatively, make the data store return an already cloned ability so that you don't expose the prototypes.
Finally, you can consider using a scripting language, e.g. javascript, to change the behavior of the generic ability. In this case all of your abilities would be stored in a folder scripts/abilities/ which you load at runtime and only the ones you need. Some arbitrary example: (heal.js file)
function onUse(object, healValue) {
if (object.hasComponent(HP_COMPONENT)) {
val hp = object.getComponent(HP_COMPONENT);
hp.value += healValue;
}
}
Here's an article that shows how to call javascript functions inside java.

You are looking for the Factory Pattern. I've found a good article about it here: http://alvinalexander.com/java/java-factory-pattern-example
I assume that you do not have to sideload class files at runtime? If that were the case I'd suggest to take a look here: Method to dynamically load java class files

Related

Using the Command Pattern with Parameters

I have a ReloadableWeapon class like this:
public class ReloadableWeapon {
private int numberofbullets;
public ReloadableWeapon(int numberofbullets){
this.numberofbullets = numberofbullets;
}
public void attack(){
numberofbullets--;
}
public void reload(int reloadBullets){
this.numberofbullets += reloadBullets;
}
}
with the following interface:
public interface Command {
void execute();
}
and use it like so:
public class ReloadWeaponCommand implements Command {
private int reloadBullets;
private ReloadableWeapon weapon;
// Is is okay to specify the number of bullets?
public ReloadWeaponCommand(ReloadableWeapon weapon, int bullets){
this.weapon = weapon;
this.reloadBullets = bullets;
}
#Override
public void execute() {
weapon.reload(reloadBullets);
}
}
Client:
ReloadableWeapon chargeGun = new ReloadableWeapon(10);
Command reload = new ReloadWeaponCommand(chargeGun,10);
ReloadWeaponController controlReload = new ReloadWeaponController(reload);
controlReload.executeCommand();
I was wondering, with the command pattern, with the examples I've seen, other than the object that the command is acting on, there are no other parameters.
This example, alters the execute method to allow for a parameter.
Another example, more close to what I have here, with parameters in the constructor.
Is it bad practice/code smell to include parameters in the command pattern, in this case the constructor with the number of bullets?
I don't think adding parameters into execute will be bad design or violate command pattern.
It totally depends on how you want to use Command Object: Singleton Or Prototype scope.
If you use Prototype scope, you can pass command parameters in Constructor methods. Each command instance has its own parameters.
If you use Singleton scope (shared/reused instance), you can pass command parameters in execute method. The singleton of the command should be thread safe for this case. This solution is a friend of IoC/DI framework too.
The very purpose of this pattern is to allow to define actions, and to execute them later, once or several times.
The code you provide is a good example of this pattern : you define the action "reload", that charges the gun with an amount of bullets=10 ammunition.
Now, if you decide to modify this code to add bullets as a parameter, then you completely lose the purpose of this pattern, because you will have to define the amount of ammunition every time.
IMHO, you can keep your code as it is. You will have to define several ReloadWeaponCommand instances, with different value of bullets. Then you may have to use another pattern (such as Strategy) to switch between the commands.
Consider a case you have 95 bullets in hand in starting, and you have made 9 commands with 10 bullets and 1 command with 5 bullets. And you have submitted these commands to Invoker, now invoker doesn't have to worry about how much bullets are left. He will just execute the command. On the other hand if invoker has to provide the no of bullets at run time then it could be the case supplied number of bullets are not available.
My point here is that Invoker must not have to worry about any extra information needs to execute the command. And as mentioned in wiki "an object is used to encapsulate all information needed to perform an action or trigger an event at a later time"
Using the Command Pattern with Parameters
Consider the related 'Extension Patterns' in order to hold to a Top-Down Control paradigm 'Inversion of Control'.
This pattern, the Command Pattern, is commonly used in concert with the Composite, Iterator, and Visitor Design Patterns.
Commands are 'First Class Objects'. So it is critical that the integrity of their encapsulation is protected. Also, inverting Control From Top Down to Bottom Up, Violates a Cardinal principle of Object Oriented Design, though I see people suggesting it all of the time...
The Composite pattern will allow you to store Commands, in iterative data structures.
Before going any further, and while your code is still manageable, look at these Patterns.
There are some reasonable points made here in this thread. #Loc has it closest IMO, However, If you consider the patterns mentioned above, then, regardless of the scope of your project (it appears that you intend to make a game, no small task) you will be able to remain in control of lower-level dependency. As #Loc pointed out, with 'Dependency Injection' lower class Objects should be kept 'in the dark' when it comes to any specific implementation, in terms of the data that is consumed by them; this is (should be) reserved for the top level hierarchy. 'Programming to Interfaces, not Implementation'.
It seems that you have a notion of this. Let me just point out where I see a likely mistake at this point. Actually a couple, already, you are focused on grains of sand I.e. "Bullets" you are not at the point where trivialities like that serve any purpose, except to be a cautionary sign, that you are presently about to lose control of higher level dependencies.
Whether you are able to see it yet or not, granular parts can and should be dealt with at higher levels. I will make a couple of suggestions. #Loc already mentioned the best practice 'Constructor Injection' loosely qualified, better to maybe look up this term 'Dependency Injection'.
Take the Bullets for e.g. Since they have already appeared on your scope. The Composite Pattern is designed to deal with many differing yet related First Class Objects e.g. Commands. Between the Iterator and Visitor Patterns you are able to store all of your pre-instantiated Commands, and future instantiations as well, in a dynamic data structure, like a Linked List OR a Binary Search Tree even. At this point forget about the Strategy
Pattern, A few possible scenarios is one thing, but It makes no sense to be writing adaptive interfaces at the outset.
Another thing, I see no indication that you are spawning projectiles from a class, bullets I mean. However, even if it were just a matter of keeping track of weapon configurations, and capacities(int items) (I'm only guessing that is the cause of necessary changes in projectile counts) use a stack structure or depending on what the actual scenario is; a circular queue. If you are actually spawning projectiles from a factory, or if you decide to in the future, you are ready to take advantage of Object Pooling; which, as it turns out, was motivated by this express consideration.
Not that anyone here has done this, but I find it particularly asinine for someone to suggest that it is ok to mishandle or disregard a particular motivation behind any established (especially GoF) Design pattern. If you find yourself having to modify a GoF Design pattern, then you are using the wrong one. Just sayin'
P.S. if you absolutely must, why don't you instead, use a template solution, rather than alter an intentionally specific Interface design;

A better way to call static methods in user-submitted code?

I have a large data set. I am creating a system which allows users to submit java source files, which will then be applied to the data set. To be more specific, each submitted java source file must contain a static method with a specific name, let's say toBeInvoked(). toBeInvoked will take a row of the data set as an array parameter. I want to call the toBeInvoked method of each submitted source file on each row in the data set. I also need to implement security measures (so toBeInvoked() can't do I/O, can't call exit, etc.).
Currently, my implementation is this: I have a list of the names of the java source files. For each file, I create an instance of the custom secure ClassLoader which I coded, which compiles the source file and returns the compiled class. I use reflection to extract the static method toBeInvoked() (e.g. method = c.getMethod("toBeInvoked", double[].class)). Then, I iterate over the rows of the data set, and invoke the method on each row.
There are at least two problems with my approach:
it appears to be painfully slow (I've heard reflection tends to be slow)
the code is more complicated than I would like
Is there a better way to accomplish what I am trying to do?
There is no significantly better approach given the constraints that you have set yourself.
For what it is worth, what makes this "painfully slow" is compiling the source files to class files and loading them. That is many orders of magnitude slower than the use of reflection to call the methods.
(Use of a common interface rather than static methods is not going to make a measurable difference to speed, and the reduction in complexity is relatively small.)
If you really want to simplify this and speed it up, change your architecture so that the code is provided as a JAR file containing all of the compiled classes.
Assuming your #toBeInvoked() could be defined in an interface rather than being static (it should be!), you could just load the class and cast it to the interface:
Class<? extends YourInterface> c = Class.forName("name", true, classLoader).asSubclass(YourInterface.class);
YourInterface i = c.newInstance();
Afterwards invoke #toBeInvoked() directly.
Also have a look into java.util.ServiceLoader, which could be helpful for finding the right class to load in case you have more than one source file.
Personally, I would use an interface. This will allow you to have multiple instance with their own state (useful for multi-threading) but more importantly you can use an interface, first to define which methods must be implemented but also to call the methods.
Reflection is slow but this is only relative to other options such as a direct method call. If you are scanning a large data set, the fact you have to pulling data from main memory is likely to be much more expensive.
I would suggest following steps for your problem.
To check if the method contains any unwanted code, you need to have a check script which can do these checks at upload time.
Create an Interface having a method toBeInvoked() (not a static method).
All the classes which are uploaded must implement this interface and add the logic inside this method.
you can have your custom class loader scan a particular folder for new classes being added and load them accordingly.
When a file is uploaded and successfully validated, you can compile and copy the class file to the folder which class loader scans.
You processor class can lookup for new files and then call toBeInvoked() method on loaded class when required.
Hope this help. (Note that i have used a similar mechanism to load dynamically workflow step classes in Workflow Engine tool which was developed).

Is it an ok practice to have a member ClientBundle in a containing ClientBundle?

In my app, I have MyAppResources, which will mainly contain custom styles for the app. I am thinking about what is a good way to go about applying custom styles to standard widgets, such as a CellTable, along with custom styles on the layout and custom widgets?
My question:
Since MyAppResources is a singleton (it doesn't have to be, as mentioned in other posts), but CellTableResources isn't, and CellTableResources is a member of this instance that is an interface also extending ClientBundle, will a proxy 'CellTableResources' be created on every MyAppResources.INSTANCE.cellTableResources().foo()?
If so, could I create a MyAppResources.CELLTABLE_RESOURCE_INSTANCE to get around this? Or would the creation of the proxy be negligible, even if there are plentiful calls to MyAppResources.INSTANCE.cellTableResources().#?
Secondly, more of a discussion question: what is best practice in regards to using multiple ClientBundles in this case? Should I instead use CellTableResources seperately (remove it from MyAppResources), using GWT.create(CellTableResources.class); in a widget that needs it (or using a singleton like I have for MyAppResources)?
MyAppResources:
public interface MyAppResources extends ClientBundle {
public static final MyAppResources INSTANCE = GWT.create(MyAppResources.class);
#Source("MyAppStyles.css")
public MyAppCssResource css();
public CellTableResources cellTableResources();
}
CellTableResources:
public interface CellTableResources extends CellTable.Resources {
interface CellTableStyle extends CellTable.Style {
}
#Override
#Source({ CellTable.Style.DEFAULT_CSS, "CellTableStyles.css" })
CellTableStyle cellTableStyle();
#Source("green_light.png")
ImageResource getGreenLight();
//...
}
Thank you for reading.
Multi-part question, so I'm going to try to hit this in several parts:
What is the cost of GWT.create()?
Most of the GWT class is 'magic', things that you cannot wrote for yourself in other ways, as they call on the compiler to fill in specific details for you. These are often different when running in dev mode vs compiled to JS.
In the case of GWT.create, it turns out that this is compiled out to new - it is used just to create new instances. So what is the cost of a new instance versus a singleton? This depends entirely on the object being created. If there are no fields in the object, then the cost is essentially free - in fact, the compiler may choose to actually remove the constructor call, and rewrite all later methods as static anyway!
This is what happens in most cases - GWT.create should be considered to be very cheap, unless you are doing something silly like calling it within a loop that is run many times.
What happens when I list a ClientBundle method inside another ClientBundle?
Well, what happens when you list anything inside a ClientBundle?
Anything that can be listed in a ClientBundle must be annotated with #ResourceGeneratorType, indicating how to generate that type. For example, here is ImageResource:
/**
* Provides access to image resources at runtime.
*/
#DefaultExtensions(value = {".png", ".jpg", ".gif", ".bmp"})
#ResourceGeneratorType(ImageResourceGenerator.class)
public interface ImageResource extends ResourcePrototype {
//...
It calls on ImageResourceGenerator to create images as needed. Any class described in that annotation must implement com.google.gwt.resources.ext.ResourceGenerator, which describes how to get ready to work, how to create necessary fields, how to initialize them, and how to finish up.
So what does this look like for ClientBundle itself? Check out com.google.gwt.resources.rg.BundleResourceGenerator - it is a very simple class that just calls GWT.create() on the type of the method given. So, predictable, this means that those 'child' ClientBundles are created via GWT.create, more or less the same as you might otherwise do.
Okay, what does that mean in this specific case?
It turns out that ClientBundles instances don't have fields where they track newly created objects from, but instead have static members that they use instead - effectively singletons. This means that once you have called a method once, the instance it returns will be the same instance created as the next time you call it. Two different ClientBundles with the same contents will of course then keep two different copies of the objects, but it doesn't matter how many times you create a ClientBundle - its internals will always be the same.
Anything else?
Yep! Remember that you are dealing with interfaces here, not classes, so you can actually extend more than once at once!
public interface MyAppResources extends
ClientBundle,
CellTable.Resources,
CellTree.Resources {//etc
//...
Now, if two interfaces describe the same methods you may have problems, but if not, this can provide an advantage when generated sprited images. Each individual ClientBundle will draw on its own pool of images when preparing them for use - if you have a ClientBundle within a ClientBundle, they won't work together to sprite images into bigger pieces. To get that, you need to make just one ClientBundle type. This may not matter in your particular case, but I figured it was also worth mentioning.

Generating code for converting between classes

In one of the project I'm working on, we have different systems.
Since those system should evolve independently we have a number of CommunicationLib to handle communication between those Systems.
CommunicationLib objects are not used inside any System, but only in communication between systems.
Since many functionality require data retrieval, I am often forced to create "local" system object that are equal to CommLib objects. I use Converter Utility class to convert from such objects to CommLib objects.
The code might look like this:
public static CommLibObjX objXToCommLib(objX p) {
CommLibObjX b = new CommLibObjX();
b.setAddressName(p.getAddressName());
b.setCityId(p.getCityId());
b.setCountryId(p.getCountryId());
b.setFieldx(p.getFieldx());
b.setFieldy(p.getFieldy());
[...]
return b;
}
Is there a way to generate such code automatically? Using Eclipse or other tools? Some field might have a different name, but I would like to generate a Converter method draft and edit it manually.
try Apache commons-beanutils
BeanUtils.copyProperties(p, b);
It copies property values from the origin bean to the destination bean for all cases where the property names are the same
If you feel the need to have source code automatically generated, you are probably doing something wrong. I think you need to reexamine the design of the communication between your two "systems". How do these "systems" communicate?
If they are on different computers or in different processes, design a wire protocol for them to use, rather than serializing objects.
If they are classes used together, design better entity classes, which are suitable for them both.

What's the proper way of declaring project constants in Java?

This may seems a silly question for Java developers, however, I'm new to Java, and my background is from low level c.
I used to include an header file with all the constants that were relevant for my projects. (usually #define's).
I'm working on a big Java project now, and there a few constants I need to make global (they fit in more than one class, and used in various parts of the project )
It makes it hard for me to decide where to put it, should I declare the same constant few times, one in each class ?
A lot of framework, uses XML files to declare constants & definitions for the framework (Hibernate, Log4J, etc.) Is it wise to use this kind of technique in my project ? if so, how can it be done easily ?
As with many things, there are many ways to do it. One thing you should not do is declare them multiple times - that's just plain silly. :P
Everything has to be in a class in Java, so either:
Pick a "main" class (say I have a project called "FTPServerApp" - I could put them there)
Create a "Util" class that contains all of them
When you figure out where to put them, declare them all this way:
public static final [type] [NAME_IN_ALL_CAPS] = [value];
This will
make them available to all your project code, anywhere (public)
only one copy of the value exists across all instances of the class (static)
they cannot be changed (final).
The ALL_CAPS_FOR_CONSTANT_NAMES, separated by underscores, is the convention in Java.
So, if this was declared in a class called FTPServerAPP, and you had a constant called SERVICE_PORT it might be:
public class FTPServerApp {
public static final int SERVICE_PORT = 21;
...
}
...and you would access it, from any class, like this...
FTPServerApp.SERVICE_PORT
Take a look at enumeration types (http://download.oracle.com/javase/tutorial/java/javaOO/enum.html) They are supposed to provide a mechanism to supply constants without defining a concrete class (or an Interface with the desired constants, as is another option that people use).
One other technique I find helpful (similar to the FTPServerApp example given above) is to define a Context for whatever subsystem/component/etc... that holds not only the constants needed by components in that system, but can hold any state that you want to make more visible or don't want individual components to hold. I believe this is along the lines of one of the GoF patterns, but it has been so long since I have looked at that book that I can't be certain (and I am too lazy to look it up right now!)

Categories

Resources