The latest example, with garbage removed
class WorldPhysXModule extends AbstractModule {
val world: WorldPhysX = new WorldPhysX
@Provides
@Singleton
@Named("dimensionScale") def dimensionScale(settings: IProperties): Float
= settings.getFloat("dimensionScale")
@Provides
@Singleton
def provideWorld(settings: IProperties) = {
val subStep1: Float = 1f / settings.getFloat("subStep1")
val subStep2: Int = settings.getInt("subStep2")
world.setGravity(0, settings.getFloat("gravity"), 0)
world.setTiming(subStep1, subStep2)
world.setStepSize(settings.getFloat("stepSize"))
world.setEnableContactUserReport(true)
world;
}
def configure {
requestInjection(world);
bind(classOf[GroundPlaneActor]).toInstance(new GroundPlaneActor(world,
"groundPlane", 1000, 0.00f))
}
}
On Mon, Mar 10, 2014 at 11:21 PM, Nate Bauernfeind <
[email protected]> wrote:
> It's nice to see another scala fan. You may consider checking out
> scala-guice ... some helper stuff that makes guice more scala friendly.
> https://github.com/codingwell/scala-guice
>
> It seems odd that you're extending Module directly; I think I've only ever
> needed to use AbstractModule or PrivateModule. Also, since, world doesn't
> have any guice annotations, then you shouldn't need to call
> requestInjection on it; since that should be a no-op. I also don't think
> you need to request injection on the binder... it seems out of place from
> my experience.
>
> Nate
>
>
> On Mon, Mar 10, 2014 at 5:11 PM, Mikkel Petersen <[email protected]>wrote:
>
>> in case anyone has the same problem..this is my solution so far (a real
>> world example)
>>
>> class WorldPhysXModule extends Module {
>> val world: WorldPhysX = new WorldPhysX
>> @Provides
>> @Singleton
>> @Named("dimensionScale") def dimensionScale(settings: IProperties):
>> Float = settings.getFloat("dimensionScale")
>>
>> @Provides
>> @Singleton
>> def provideWorld(settings: IProperties) = {
>> val subStep1: Float = 1f / settings.getFloat("subStep1")
>> val subStep2: Int = settings.getInt("subStep2")
>> world.setGravity(0, settings.getFloat("gravity"), 0)
>> world.setTiming(subStep1, subStep2)
>> world.setStepSize(settings.getFloat("stepSize"))
>> world.setEnableContactUserReport(true)
>> world;
>> }
>> def configure(binder: Binder) {
>> binder.requestInjection(binder)
>> binder.requestInjection(world);
>> binder.bind(classOf[GroundPlaneActor]).toInstance(new
>> GroundPlaneActor(world, "groundPlane", 1000, 0.00f))
>> }
>>
>> }
>>
>> Note that "WorldPhysx" does not know anything about guice, so we have to
>> access the setters directly..
>> To ensure that also "World" gets injected, call requestInjection in
>> configure but dont BIND it here..do that in provides..anyway that's my
>> fifty cent.
>>
>> Den mandag den 10. marts 2014 22.36.27 UTC+1 skrev Mikkel Petersen:
>>
>>> Still, since not all classes are injectable (third party) you might need
>>> to access them and populate them manually..
>>>
>>> Den mandag den 10. marts 2014 21.27.38 UTC+1 skrev Nate Bauernfeind:
>>>>
>>>> No actually you don't get already bound exceptions. Guice actually
>>>> treats the injection as a setter based injection (it doesn't care how you
>>>> name methods; but I tend to use the word register since it seems to suggest
>>>> not saving the object).
>>>>
>>>> So if you're thinking on the Abstract case you'd have something like
>>>> this:
>>>>
>>>> abstract class AbstractThing {
>>>> @Inject
>>>> private void registerThing(ThingService service) {
>>>> service.registerThing(this) }
>>>> }
>>>>
>>>> class Thing1 extends AbstractThing {
>>>> ...
>>>> }
>>>>
>>>> class Thing2 extends AbstractThing {
>>>> ...
>>>> }
>>>>
>>>> and in your configure method you can just do:
>>>>
>>>> bind(Thing1.class).asEagerSingleton()
>>>> bind(Thing2.class).asEagerSingleton()
>>>>
>>>> And the magic just happens. It doesn't matter if Thing1/Thing2 are in
>>>> the same module or separate modules as long as the ThingService exists
>>>> somewhere and are being created as part of the same injector. And note that
>>>> the private classifier allows you to hide the fact that Guice is going to
>>>> do this for you. So you never have to worry about users of Thing1/Thing2
>>>> abusing that method (at-least I like making it private; your milage may
>>>> vary =P).
>>>>
>>>> If you bind AbstractThing to Thing1 and to Thing2 you will get an
>>>> already bound exception. But the AbstractThing class doesn't need to show
>>>> up in any bindings for the injection to occur.
>>>>
>>>> Good luck,
>>>> Nate
>>>>
>>>> On Mon, Mar 10, 2014 at 3:15 PM, Mikkel Petersen <[email protected]>wrote:
>>>>
>>>>> This sounds like a good idea but wont to get a "Already bound"
>>>>> exception ?
>>>>>
>>>>>
>>>>> Den mandag den 10. marts 2014 20.26.26 UTC+1 skrev Nate Bauernfeind:
>>>>>
>>>>>> Just finished reading through the stack overflow link; thanks for
>>>>>> sharing it. It reminded me of the following:
>>>>>>
>>>>>> I've heard/read/adopted the policy that guice modules should
>>>>>> sincerely avoid any conditional logic. If you do find yourself with some
>>>>>> conditional logic try and split your module up by either moving the
>>>>>> conditional logic into a provider or up into multiple modules and let
>>>>>> your
>>>>>> application choose which module(s) based on the appropriate mode(s). It's
>>>>>> hard to do, and I probably don't have one project that is conditional
>>>>>> free
>>>>>> in all configure methods... but that certainly helps defer the need to
>>>>>> inject some things into a guice module.
>>>>>>
>>>>>> Next, I wanted to point out one pattern I've used quite often when it
>>>>>> comes to registering objects for some purpose (like listening to events,
>>>>>> or
>>>>>> even to enable key-based delegation to that object). Typically you'll
>>>>>> have
>>>>>> a main service you want to register to listen/subscribe on, which I'll
>>>>>> use
>>>>>> the example of a DaoService. Users of the DaoService can subscribe to the
>>>>>> Dao to listen for events that occur on any sub-class of a type. So some
>>>>>> handwaving:
>>>>>>
>>>>>> class DaoService {
>>>>>> public synchronized void addListener(Class<T> type, DaoListener<T>
>>>>>> listener) {...}
>>>>>> }
>>>>>>
>>>>>> public interface DaoListener<T> {
>>>>>> public void dataAdded(T data) throws Exception;
>>>>>> public void dataUpdated(T oldData, T newData) throws Exception;
>>>>>> public void dataRemoved(T data) throws Exception;
>>>>>> }
>>>>>>
>>>>>> And then in my user class (and sometimes this is an abstract base
>>>>>> class) I use setter injection specifically to register the listener:
>>>>>>
>>>>>> class ExampleUser {
>>>>>> private Listener _listener = new Listener();
>>>>>>
>>>>>> @Inject
>>>>>> public ExampleUser(...) {...}
>>>>>>
>>>>>> @Inject
>>>>>> private void registerAsDaoListener(DaoService service) {
>>>>>> service.addListener(MyDataType.class, _listener);
>>>>>> }
>>>>>>
>>>>>> private final class Listener implements DaoListener<MyDataType> {
>>>>>> ...
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> So, again, in this example I'm decoupling the idea of who is
>>>>>> listening to what data. Obviously the sender / daoService needs to be
>>>>>> around (unlike in the event bus example), but now no one ever needs to
>>>>>> know
>>>>>> about how many listeners there are (depending on how you store your
>>>>>> listeners you may need to make sure you're not overwriting any other
>>>>>> listener in the addListener method).
>>>>>>
>>>>>> And.. I also use Scala as often as I can, so sometimes pieces of
>>>>>> these end up in a trait that is easy to mix-in for the repeated
>>>>>> functionality (like managing the listener map/list).
>>>>>>
>>>>>> So.. maybe this would be a good alternative to the multibinding
>>>>>> extension for you. I've used it with great success (esp. when the
>>>>>> register
>>>>>> method is on an abstract base class).
>>>>>>
>>>>>> Good luck and happy Guicing =),
>>>>>> Nate
>>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "google-guice" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> Visit this group at http://groups.google.com/group/google-guice.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>> --
>> You received this message because you are subscribed to the Google Groups
>> "google-guice" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>>
>> To post to this group, send email to [email protected].
>> Visit this group at http://groups.google.com/group/google-guice.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "google-guice" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/google-guice/HMj5hmPjmR4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/google-guice.
> For more options, visit https://groups.google.com/d/optout.
>
--
Med venlig hilsen/Best regards
Mikkel Petersen
Jagtvej 82 4th
2200 København N
Telefon 35 37 63 10
Mobil 91 97 03 64
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/d/optout.